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 <stdbool.h>
128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <string.h> /* for memset */
138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <errno.h>
148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <assert.h>
158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include "internal/internal.h"
178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \mainpage
208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * libnetfilter_conntrack is a userspace library providing a programming
228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * interface (API) to the in-kernel connection tracking state table. The
238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * library libnetfilter_conntrack has been previously known as
248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * libnfnetlink_conntrack and libctnetlink. This library is currently used by
258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * conntrack-tools among many other applications.
268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * libnetfilter_conntrack homepage is:
288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *      http://netfilter.org/projects/libnetfilter_conntrack/
298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \section Dependencies
318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * libnetfilter_conntrack requires libnfnetlink and a kernel that includes the
328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nf_conntrack_netlink subsystem (i.e. 2.6.14 or later, >= 2.6.18 recommended).
338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \section Main Features
358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *  - listing/retrieving entries from the kernel connection tracking table.
368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *  - inserting/modifying/deleting entries from the kernel connection tracking
378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *    table.
388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *  - listing/retrieving entries from the kernel expect table.
398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *  - inserting/modifying/deleting entries from the kernel expect table.
408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \section Git Tree
418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The current development version of libnetfilter_conntrack can be accessed at
428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * https://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnetfilter_conntrack.git
438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \section Privileges
458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * You need the CAP_NET_ADMIN capability in order to allow your application
468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * to receive events from and to send commands to kernel-space, excepting
478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the conntrack table dumping operation.
488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \section using Using libnetfilter_conntrack
508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * To write your own program using libnetfilter_conntrack, you should start by
518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * reading the doxygen documentation (start by \link LibrarySetup \endlink page)
528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * and check examples available under utils/ in the libnetfilter_conntrack
538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * source code tree. You can compile these examples by invoking `make check'.
548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \section Authors
568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * libnetfilter_conntrack has been almost entirely written by Pablo Neira Ayuso.
578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \section python Python Binding
598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * pynetfilter_conntrack is a Python binding of libnetfilter_conntrack written
608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * by Victor Stinner. You can visit his official web site at
618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * http://software.inl.fr/trac/trac.cgi/wiki/pynetfilter_conntrack.
628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup ct Conntrack object handling
668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_conntrack_new - allocate a new conntrack
718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * In case of success, this function returns a valid pointer to a memory blob,
738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * otherwise NULL is returned and errno is set appropiately.
748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
758a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nf_conntrack *nfct_new(void)
768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nf_conntrack *ct;
788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	ct = malloc(sizeof(struct nf_conntrack));
808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!ct)
818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(ct, 0, sizeof(struct nf_conntrack));
848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ct;
868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nf_conntrack_destroy - release a conntrack object
908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to the conntrack object
918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
928a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_destroy(struct nf_conntrack *ct)
938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (ct->secctx)
968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		free(ct->secctx);
978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (ct->helper_info)
988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		free(ct->helper_info);
998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (ct->connlabels)
1008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfct_bitmask_destroy(ct->connlabels);
1018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (ct->connlabels_mask)
1028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfct_bitmask_destroy(ct->connlabels_mask);
1038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(ct);
1048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	ct = NULL; /* bugtrap */
1058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nf_sizeof - return the size in bytes of a certain conntrack object
1098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to the conntrack object
1108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function is DEPRECATED, don't use it in your code.
1128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1138a44513648da0c5f5551f96b329cf56b66f5b303pkanwarsize_t nfct_sizeof(const struct nf_conntrack *ct)
1148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
1168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return sizeof(*ct);
1178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_maxsize - return the maximum size in bytes of a conntrack object
1218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Use this function if you want to allocate a conntrack object in the stack
1238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * instead of the heap. For example:
1248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \verbatim
1258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	char buf[nfct_maxsize()];
1268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nf_conntrack *ct = (struct nf_conntrack *) buf;
1278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(ct, 0, nfct_maxsize());
1288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar\endverbatim
1298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note: As for now this function returns the same size that nfct_sizeof(ct)
1308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * does although _this could change in the future_. Therefore, do not assume
1318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * that nfct_sizeof(ct) == nfct_maxsize().
1328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function is DEPRECATED, don't use it in your code.
1348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1358a44513648da0c5f5551f96b329cf56b66f5b303pkanwarsize_t nfct_maxsize(void)
1368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return sizeof(struct nf_conntrack);
1388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_clone - clone a conntrack object
1428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
1438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, NULL is returned and errno is appropiately set. Otherwise,
1458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * a valid pointer to the clone conntrack is returned.
1468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1478a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nf_conntrack *nfct_clone(const struct nf_conntrack *ct)
1488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nf_conntrack *clone;
1508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
1528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if ((clone = nfct_new()) == NULL)
1548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
1558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_copy(clone, ct, NFCT_CP_OVERRIDE);
1568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return clone;
1588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_setobjopt - set a certain option for a conntrack object
1628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct conntrack object
1638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param option option parameter
1648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * In case of error, -1 is returned and errno is appropiately set. On success,
1668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
1678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1688a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_setobjopt(struct nf_conntrack *ct, unsigned int option)
1698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
1718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(option > NFCT_SOPT_MAX)) {
1738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EOPNOTSUPP;
1748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
1758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
1768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __setobjopt(ct, option);
1788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_getobjopt - get a certain option for a conntrack object
1828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct conntrack object
1838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param option option parameter
1848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * In case of error, -1 is returned and errno is appropiately set. On success,
1868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
1878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1888a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_getobjopt(const struct nf_conntrack *ct, unsigned int option)
1898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
1918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(option > NFCT_GOPT_MAX)) {
1938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EOPNOTSUPP;
1948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
1958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
1968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __getobjopt(ct, option);
1988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
2028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup LibrarySetup Library setup
2068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
2078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nf_callback_register - register a callback
2118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
2128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type message type (see enum nf_conntrack_msg_type definition)
2138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param cb callback used to process conntrack received
2148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data used by the callback, if any.
2158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function register a callback to handle the conntrack received,
2178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * in case of error -1 is returned and errno is set appropiately, otherwise
2188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
2198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that the data parameter is optional, if you do not want to pass any
2218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * data to your callback, then use NULL.
2228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2238a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_callback_register(struct nfct_handle *h,
2248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   enum nf_conntrack_msg_type type,
2258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   int (*cb)(enum nf_conntrack_msg_type type,
2268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   	     struct nf_conntrack *ct,
2278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				     void *data),
2288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   void *data)
2298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
2308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct __data_container *container;
2318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
2338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container = malloc(sizeof(struct __data_container));
2358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!container)
2368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
2378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(container, 0, sizeof(struct __data_container));
2388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->cb = cb;
2408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->h = h;
2418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->type = type;
2428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->data = data;
2438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.call = __callback;
2458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.data = container;
2468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.attr_count = CTA_MAX;
2478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_ct,
2498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_CT_NEW,
2508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_ct);
2518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_ct,
2538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_CT_DELETE,
2548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_ct);
2558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
2578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
2588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_callback_unregister - unregister a callback
2618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
2628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2638a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_callback_unregister(struct nfct_handle *h)
2648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
2658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
2668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
2688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
2698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->cb = NULL;
2718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(h->nfnl_cb_ct.data);
2728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.call = NULL;
2748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.data = NULL;
2758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.attr_count = 0;
2768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
2778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nf_callback_register2 - register a callback
2808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
2818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param cb callback used to process conntrack received
2828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data used by the callback, if any.
2838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function register a callback to handle the conntrack received,
2858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * in case of error -1 is returned and errno is set appropiately, otherwise
2868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
2878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that the data parameter is optional, if you do not want to pass any
2898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * data to your callback, then use NULL.
2908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NOTICE: The difference with nf_callback_register() is that this function
2928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * uses the new callback interface that includes the Netlink header.
2938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * WARNING: Don't mix nf_callback_register() and nf_callback_register2()
2958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * calls, use only once at a time.
2968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2978a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_callback_register2(struct nfct_handle *h,
2988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    enum nf_conntrack_msg_type type,
2998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    int (*cb)(const struct nlmsghdr *nlh,
3008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    	      enum nf_conntrack_msg_type type,
3018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				      struct nf_conntrack *ct,
3028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				      void *data),
3038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   void *data)
3048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct __data_container *container;
3068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
3088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container = calloc(sizeof(struct __data_container), 1);
3108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (container == NULL)
3118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
3128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->cb2 = cb;
3148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->h = h;
3158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->type = type;
3168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->data = data;
3178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.call = __callback;
3198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.data = container;
3208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.attr_count = CTA_MAX;
3218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_ct,
3238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_CT_NEW,
3248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_ct);
3258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_ct,
3278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_CT_DELETE,
3288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_ct);
3298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
3318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_callback_unregister2 - unregister a callback
3358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
3368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3378a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_callback_unregister2(struct nfct_handle *h)
3388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
3408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
3428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
3438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->cb2 = NULL;
3458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(h->nfnl_cb_ct.data);
3468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.call = NULL;
3488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.data = NULL;
3498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_ct.attr_count = 0;
3508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
3548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup ct Conntrack object handling
3588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
3598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr_l - set the value of a certain conntrack attribute
3638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
3648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param pointer to attribute value
3668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param length of attribute value (in bytes)
3678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3688a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid
3698a44513648da0c5f5551f96b329cf56b66f5b303pkanwarnfct_set_attr_l(struct nf_conntrack *ct, const enum nf_conntrack_attr type,
3708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		const void *value, size_t len)
3718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
3738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(value != NULL);
3748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_MAX))
3768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return;
3778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (set_attr_array[type]) {
3798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_attr_array[type](ct, value, len);
3808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_bit(type, ct->head.set);
3818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
3828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr - set the value of a certain conntrack attribute
3868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
3878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value pointer to the attribute value
3898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
3908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that certain attributes are unsettable:
3918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- ATTR_USE
3928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- ATTR_ID
3938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- ATTR_*_COUNTER_*
3948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *	- ATTR_SECCTX
3958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *	- ATTR_TIMESTAMP_*
3968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The call of this function for such attributes do nothing.
3978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3988a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_set_attr(struct nf_conntrack *ct,
3998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		   const enum nf_conntrack_attr type,
4008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		   const void *value)
4018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	/* We assume the setter knows the size of the passed pointer. */
4038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_set_attr_l(ct, type, value, 0);
4048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr_u8 - set the value of a certain conntrack attribute
4088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
4098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value unsigned 8 bits attribute value
4118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4128a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_set_attr_u8(struct nf_conntrack *ct,
4138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      const enum nf_conntrack_attr type,
4148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      uint8_t value)
4158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_set_attr_l(ct, type, &value, sizeof(uint8_t));
4178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr_u16 - set the value of a certain conntrack attribute
4218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
4228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value unsigned 16 bits attribute value
4248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4258a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_set_attr_u16(struct nf_conntrack *ct,
4268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const enum nf_conntrack_attr type,
4278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       uint16_t value)
4288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_set_attr_l(ct, type, &value, sizeof(uint16_t));
4308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr_u32 - set the value of a certain conntrack attribute
4348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
4358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value unsigned 32 bits attribute value
4378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4388a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_set_attr_u32(struct nf_conntrack *ct,
4398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const enum nf_conntrack_attr type,
4408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       uint32_t value)
4418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_set_attr_l(ct, type, &value, sizeof(uint32_t));
4438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr_u64 - set the value of a certain conntrack attribute
4478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
4488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value unsigned 64 bits attribute value
4508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4518a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_set_attr_u64(struct nf_conntrack *ct,
4528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const enum nf_conntrack_attr type,
4538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       uint64_t value)
4548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_set_attr_l(ct, type, &value, sizeof(uint64_t));
4568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_get_attr - get a conntrack attribute
4608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
4618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
4638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * In case of success a valid pointer to the attribute requested is returned,
4648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * on error NULL is returned and errno is set appropiately.
4658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4668a44513648da0c5f5551f96b329cf56b66f5b303pkanwarconst void *nfct_get_attr(const struct nf_conntrack *ct,
4678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			  const enum nf_conntrack_attr type)
4688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
4708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_MAX)) {
4728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
4738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
4748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
4758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!test_bit(type, ct->head.set)) {
4778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = ENODATA;
4788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
4798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
4808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(get_attr_array[type]);
4828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return get_attr_array[type](ct);
4848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_get_attr_u8 - get attribute of unsigned 8-bits long
4888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
4898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
4918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Returns the value of the requested attribute, if the attribute is not
4928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * set, 0 is returned. In order to check if the attribute is set or not,
4938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfct_attr_is_set.
4948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4958a44513648da0c5f5551f96b329cf56b66f5b303pkanwaruint8_t nfct_get_attr_u8(const struct nf_conntrack *ct,
4968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			  const enum nf_conntrack_attr type)
4978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint8_t *ret = nfct_get_attr(ct, type);
4998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ret == NULL ? 0 : *ret;
5008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_get_attr_u16 - get attribute of unsigned 16-bits long
5048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
5058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
5068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Returns the value of the requested attribute, if the attribute is not
5088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * set, 0 is returned. In order to check if the attribute is set or not,
5098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfct_attr_is_set.
5108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
5118a44513648da0c5f5551f96b329cf56b66f5b303pkanwaruint16_t nfct_get_attr_u16(const struct nf_conntrack *ct,
5128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    const enum nf_conntrack_attr type)
5138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint16_t *ret = nfct_get_attr(ct, type);
5158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ret == NULL ? 0 : *ret;
5168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_get_attr_u32 - get attribute of unsigned 32-bits long
5208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
5218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
5228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Returns the value of the requested attribute, if the attribute is not
5248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * set, 0 is returned. In order to check if the attribute is set or not,
5258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfct_attr_is_set.
5268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
5278a44513648da0c5f5551f96b329cf56b66f5b303pkanwaruint32_t nfct_get_attr_u32(const struct nf_conntrack *ct,
5288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    const enum nf_conntrack_attr type)
5298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint32_t *ret = nfct_get_attr(ct, type);
5318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ret == NULL ? 0 : *ret;
5328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_get_attr_u64 - get attribute of unsigned 32-bits long
5368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack
5378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
5388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Returns the value of the requested attribute, if the attribute is not
5408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * set, 0 is returned. In order to check if the attribute is set or not,
5418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfct_attr_is_set.
5428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
5438a44513648da0c5f5551f96b329cf56b66f5b303pkanwaruint64_t nfct_get_attr_u64(const struct nf_conntrack *ct,
5448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    const enum nf_conntrack_attr type)
5458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint64_t *ret = nfct_get_attr(ct, type);
5478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ret == NULL ? 0 : *ret;
5488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_attr_is_set - check if a certain attribute is set
5528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
5538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
5548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately, otherwise
5568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the value of the attribute is returned.
5578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
5588a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_attr_is_set(const struct nf_conntrack *ct,
5598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		     const enum nf_conntrack_attr type)
5608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
5628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_MAX)) {
5648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
5658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
5668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
5678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return test_bit(type, ct->head.set);
5688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_attr_is_set_array - check if an array of attribute types is set
5728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
5738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param array attribute type array
5748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the array
5758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately, otherwise
5778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the value of the attribute is returned.
5788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
5798a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_attr_is_set_array(const struct nf_conntrack *ct,
5808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   const enum nf_conntrack_attr *type_array,
5818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   int size)
5828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	int i;
5848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
5868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	for (i=0; i<size; i++) {
5888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		if (unlikely(type_array[i] >= ATTR_MAX)) {
5898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			errno = EINVAL;
5908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			return -1;
5918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
5928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		if (!test_bit(type_array[i], ct->head.set))
5938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			return 0;
5948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
5958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 1;
5968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_attr_unset - unset a certain attribute
6008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
6018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
6028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately, otherwise
6048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
6058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6068a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_attr_unset(struct nf_conntrack *ct,
6078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		    const enum nf_conntrack_attr type)
6088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
6098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
6108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_MAX)) {
6128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
6138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
6148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
6158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unset_bit(type, ct->head.set);
6168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
6188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
6198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
6218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr_grp - set a group of attributes
6228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
6238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute group (see ATTR_GRP_*)
6248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data pointer to struct (see struct nfct_attr_grp_*)
6258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that calling this function for ATTR_GRP_COUNTER_* and ATTR_GRP_ADDR_*
6278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * have no effect.
6288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6298a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_set_attr_grp(struct nf_conntrack *ct,
6308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const enum nf_conntrack_attr_grp type,
6318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const void *data)
6328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
6338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
6348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_GRP_MAX))
6368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return;
6378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (set_attr_grp_array[type]) {
6398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_attr_grp_array[type](ct, data);
6408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_bitmask_u32(ct->head.set,
6418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				attr_grp_bitmask[type].bitmask, __NFCT_BITSET);
6428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
6438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
6448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
6468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_get_attr_grp - get an attribute group
6478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
6488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute group (see ATTR_GRP_*)
6498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data pointer to struct (see struct nfct_attr_grp_*)
6508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, it returns -1 and errno is appropriately set. On success, the
6528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * data pointer contains the attribute group.
6538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6548a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_get_attr_grp(const struct nf_conntrack *ct,
6558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      const enum nf_conntrack_attr_grp type,
6568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      void *data)
6578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
6588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
6598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_GRP_MAX)) {
6618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
6628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
6638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
6648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	switch(attr_grp_bitmask[type].type) {
6658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_BITMASK_AND:
6668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		if (!test_bitmask_u32(ct->head.set,
6678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				      attr_grp_bitmask[type].bitmask,
6688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				      __NFCT_BITSET)) {
6698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			errno = ENODATA;
6708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			return -1;
6718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
6728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
6738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_BITMASK_OR:
6748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		if (!test_bitmask_u32_or(ct->head.set,
6758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar					 attr_grp_bitmask[type].bitmask,
6768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar					 __NFCT_BITSET)) {
6778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			errno = ENODATA;
6788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			return -1;
6798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
6808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
6818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
6828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(get_attr_grp_array[type]);
6838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	get_attr_grp_array[type](ct, data);
6848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
6858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
6868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
6888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_attr_grp_is_set - check if an attribute group is set
6898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
6908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute group (see ATTR_GRP_*)
6918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If the attribute group is set, this function returns 1, otherwise 0.
6938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6948a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_attr_grp_is_set(const struct nf_conntrack *ct,
6958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 const enum nf_conntrack_attr_grp type)
6968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
6978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
6988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_GRP_MAX)) {
7008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
7018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
7028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
7038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	switch(attr_grp_bitmask[type].type) {
7048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_BITMASK_AND:
7058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		if (test_bitmask_u32(ct->head.set,
7068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				     attr_grp_bitmask[type].bitmask,
7078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				     __NFCT_BITSET)) {
7088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			return 1;
7098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
7108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
7118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_BITMASK_OR:
7128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		if (test_bitmask_u32_or(ct->head.set,
7138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar					attr_grp_bitmask[type].bitmask,
7148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar					__NFCT_BITSET)) {
7158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			return 1;
7168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
7178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
7188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
7198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
7208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
7218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_attr_grp_unset - unset an attribute group
7248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
7258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute group (see ATTR_GRP_*)
7268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, it returns -1 and errno is appropriately set. On success,
7288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * this function returns 0.
7298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7308a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_attr_grp_unset(struct nf_conntrack *ct,
7318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			const enum nf_conntrack_attr_grp type)
7328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
7338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
7348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= ATTR_GRP_MAX)) {
7368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
7378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
7388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
7398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unset_bitmask_u32(ct->head.set, attr_grp_bitmask[type].bitmask,
7408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			  __NFCT_BITSET);
7418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
7438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
7448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
7478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup nl Low level object to Netlink message
7518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
7528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_build_conntrack - build a netlink message from a conntrack object
7568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ssh nfnetlink subsystem handler
7578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param req buffer used to build the netlink message
7588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the buffer passed
7598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type netlink message type
7608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags netlink flags
7618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a conntrack object
7628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is a low level function for those that require to be close to
7648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * netlink details via libnfnetlink. If you do want to obviate the netlink
7658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * details then we suggest you to use nfct_query.
7668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is appropiately set.
7688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On success, 0 is returned.
7698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7708a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_build_conntrack(struct nfnl_subsys_handle *ssh,
7718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 void *req,
7728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 size_t size,
7738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 uint16_t type,
7748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 uint16_t flags,
7758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 const struct nf_conntrack *ct)
7768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
7778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ssh != NULL);
7788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(req != NULL);
7798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
7808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __build_conntrack(ssh, req, size, type, flags, ct);
7828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
7838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7848a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic int
7858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar__build_query_ct(struct nfnl_subsys_handle *ssh,
7868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		 const enum nf_conntrack_query qt,
7878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		 const void *data, void *buffer, unsigned int size)
7888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
7898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfnlhdr *req = buffer;
7908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint32_t *family = data;
7918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ssh != NULL);
7938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(data != NULL);
7948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(req != NULL);
7958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(req, 0, size);
7978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	switch(qt) {
7998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_CREATE:
8008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data);
8018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_UPDATE:
8038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_ACK, data);
8048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_DESTROY:
8068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_conntrack(ssh, req, size, IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST|NLM_F_ACK, data);
8078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_GET:
8098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_conntrack(ssh, req, size, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_ACK, data);
8108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_FLUSH:
8128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST|NLM_F_ACK);
8138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_DUMP:
8158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_DUMP);
8168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_DUMP_RESET:
8188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_GET_CTRZERO, NLM_F_REQUEST|NLM_F_DUMP);
8198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_CREATE_UPDATE:
8218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK, data);
8228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_DUMP_FILTER:
8248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfnl_fill_hdr(ssh, &req->nlh, 0, AF_UNSPEC, 0, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_DUMP);
8258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_filter_dump(req, size, data);
8268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_DUMP_FILTER_RESET:
8288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfnl_fill_hdr(ssh, &req->nlh, 0, AF_UNSPEC, 0, IPCTNL_MSG_CT_GET_CTRZERO, NLM_F_REQUEST|NLM_F_DUMP);
8298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_filter_dump(req, size, data);
8308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
8318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	default:
8328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = ENOTSUP;
8338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
8348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
8358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 1;
8368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
8378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
8388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
8398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_build_query - build a query in netlink message format for ctnetlink
8408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ssh nfnetlink subsystem handler
8418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param qt query type
8428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data required to build the query
8438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param req buffer to build the netlink message
8448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the buffer passed
8458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is a low level function, use it if you want to require to work
8478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * with netlink details via libnfnetlink, otherwise we suggest you to
8488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfct_query.
8498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The pointer to data can be a conntrack object or the protocol family
8518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * depending on the request.
8528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * For query types:
8548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_CREATE: add a new conntrack, if it exists, fail
8558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_O_CREATE_UPDATE: add a new conntrack, if it exists, update it
8568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_UPDATE: update a conntrack
8578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_DESTROY: destroy a conntrack
8588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_GET: get a conntrack
8598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Pass a valid pointer to a conntrack object.
8618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * For query types:
8638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_FLUSH: flush the conntrack table
8648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_DUMP: dump the conntrack table
8658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_DUMP_RESET: dump the conntrack table and reset counters
8668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_DUMP_FILTER: dump the conntrack table
8678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_Q_DUMP_FILTER_RESET: dump the conntrack table and reset counters
8688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Pass a valid pointer to the protocol family (uint32_t)
8708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On success, 0 is returned. On error, -1 is returned and errno is set
8728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * appropiately.
8738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
8748a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_build_query(struct nfnl_subsys_handle *ssh,
8758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		     const enum nf_conntrack_query qt,
8768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		     const void *data,
8778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		     void *buffer,
8788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		     unsigned int size)
8798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
8808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __build_query_ct(ssh, qt, data, buffer, size);
8818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
8828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
8838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
8848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_parse_conntrack - translate a netlink message to a conntrack object
8858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type do the translation iif the message type is of a certain type
8868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param nlh pointer to the netlink message
8878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to the conntrack object
8888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is a low level function, use it in case that you require to work
8908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * with netlink details via libnfnetlink. Otherwise, we suggest you to
8918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use the high level API.
8928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The message types are:
8948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
8958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * - NFCT_T_NEW: parse messages with new conntracks
8968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * - NFCT_T_UPDATE: parse messages with conntrack updates
8978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * - NFCT_T_DESTROY: parse messages with conntrack destroy
8988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * - NFCT_T_ALL: all message types
8998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
9008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The message type is a flag, therefore the can be combined, ie.
9018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFCT_T_NEW | NFCT_T_DESTROY to parse only new and destroy messages
9028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
9038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, NFCT_T_ERROR is returned and errno is set appropiately. If
9048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the message received is not of the requested type then 0 is returned,
9058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * otherwise this function returns the message type parsed.
9068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
9078a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_parse_conntrack(enum nf_conntrack_msg_type type,
9088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 const struct nlmsghdr *nlh,
9098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 struct nf_conntrack *ct)
9108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
9118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int flags;
9128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	int len = nlh->nlmsg_len;
9138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
9148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfattr *cda[CTA_MAX];
9158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(nlh != NULL);
9178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
9188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
9208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (len < 0) {
9218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
9228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NFCT_T_ERROR;
9238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
9248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	flags = __parse_message_type(nlh);
9268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!(flags & type))
9278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return 0;
9288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_parse_attr(cda, CTA_MAX, NFA_DATA(nfhdr), len);
9308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	__parse_conntrack(nlh, cda, ct);
9328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return flags;
9348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
9358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
9378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
9388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
9398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
9418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup cmd Send commands to kernel-space and receive replies
9428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
9438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
9448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
9468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_query - send a query to ctnetlink and handle the reply
9478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
9488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param qt query type
9498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data required to send the query
9508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
9518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is explicitely set. On success, 0
9528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * is returned.
9538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
9548a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_query(struct nfct_handle *h,
9558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	       const enum nf_conntrack_query qt,
9568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	       const void *data)
9578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
9588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const size_t size = 4096;	/* enough for now */
9598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	union {
9608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		char buffer[size];
9618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		struct nfnlhdr req;
9628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	} u;
9638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
9658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(data != NULL);
9668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (__build_query_ct(h->nfnlssh_ct, qt, data, &u.req, size) == -1)
9688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
9698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return nfnl_query(h->nfnlh, &u.req.nlh);
9718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
9728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
9748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_send - send a query to ctnetlink
9758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
9768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param qt query type
9778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data required to send the query
9788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
9798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Like nfct_query but we do not wait for the reply from ctnetlink.
9808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * You can use nfct_send() and nfct_catch() to emulate nfct_query().
9818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is particularly useful when the socket is non-blocking.
9828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
9838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is explicitely set. On success, 0
9848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * is returned.
9858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
9868a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_send(struct nfct_handle *h,
9878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	      const enum nf_conntrack_query qt,
9888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	      const void *data)
9898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
9908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const size_t size = 4096;	/* enough for now */
9918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	union {
9928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		char buffer[size];
9938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		struct nfnlhdr req;
9948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	} u;
9958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
9978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(data != NULL);
9988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
9998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (__build_query_ct(h->nfnlssh_ct, qt, data, &u.req, size) == -1)
10008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
10018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return nfnl_send(h->nfnlh, &u.req.nlh);
10038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
10048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
10078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_catch - catch events
10088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
10098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function receives the event from the kernel and it invokes the
10118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * callback that was registered to this handle.
10128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately. On success,
10148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * a value greater or equal to 0 is returned indicating the callback
10158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * verdict: NFCT_CB_STOP, NFCT_CB_CONTINUE or NFCT_CB_STOLEN.
10168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Beware that this function also handles expectation events, in case they are
10188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * received through this handle.
10198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
10208a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_catch(struct nfct_handle *h)
10218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
10228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
10238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return nfnl_catch(h->nfnlh);
10258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
10268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
10288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
10298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
10308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
10328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup ct Conntrack object handling
10338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
10348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
10358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
10378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_snprintf - print a conntrack object to a buffer
10388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param buf buffer used to build the printable conntrack
10398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the buffer
10408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
10418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param message_type print message type (NFCT_T_UNKNOWN, NFCT_T_NEW,...)
10428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param output_type print type (NFCT_O_DEFAULT, NFCT_O_XML, ...)
10438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags extra flags for the output type (NFCT_OF_LAYER3)
10448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If you are listening to events, probably you want to display the message
10468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * type as well. In that case, set the message type parameter to any of the
10478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * known existing types, ie. NFCT_T_NEW, NFCT_T_UPDATE, NFCT_T_DESTROY.
10488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If you pass NFCT_T_UNKNOWN, the message type will not be output.
10498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Currently, the output available are:
10518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_O_DEFAULT: default /proc-like output
10528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_O_XML: XML output
10538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The output flags are:
10558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_OF_SHOW_LAYER3: include layer 3 information in the output,
10568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	this is *only* required by NFCT_O_DEFAULT.
10578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_OF_TIME: display current time.
10588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_OF_ID: display the ID number.
10598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_OF_TIMESTAMP: display creation and (if exists) deletion time.
10608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * To use NFCT_OF_TIMESTAMP, you have to:
10628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \verbatim
10638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *  $ echo 1 > /proc/sys/net/netfilter/nf_conntrack_timestamp
10648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar\endverbatim
10658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This requires a Linux kernel >= 2.6.38.
10668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that NFCT_OF_TIME displays the current time when nfct_snprintf() has
10688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * been called. Thus, it can be used to know when a flow was destroy if you
10698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * print the message just after you receive the destroy event. If you want
10708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * more accurate timestamping, use NFCT_OF_TIMESTAMP.
10718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
10728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function returns the size of the information that _would_ have been
10738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * written to the buffer, even if there was no room for it. Thus, the
10748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * behaviour is similar to snprintf.
10758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
10768a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_snprintf(char *buf,
10778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int size,
10788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  const struct nf_conntrack *ct,
10798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int msg_type,
10808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int out_type,
10818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int flags)
10828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
10838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(buf != NULL);
10848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(size > 0);
10858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct != NULL);
10868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __snprintf_conntrack(buf, size, ct, msg_type, out_type, flags, NULL);
10888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
10898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
10908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
10918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_snprintf_labels - print a bitmask object to a buffer including labels
10928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param buf buffer used to build the printable conntrack
10938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the buffer
10948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct pointer to a valid conntrack object
10958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param message_type print message type (NFCT_T_UNKNOWN, NFCT_T_NEW,...)
10968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param output_type print type (NFCT_O_DEFAULT, NFCT_O_XML, ...)
10978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags extra flags for the output type (NFCT_OF_LAYER3)
10988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param map nfct_labelmap describing the connlabel translation, or NULL.
10998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * When map is NULL, the function is equal to nfct_snprintf().
11018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Otherwise, if the conntrack object has a connlabel attribute, the active
11028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * labels are translated using the label map and added to the buffer.
11038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
11048a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_snprintf_labels(char *buf,
11058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 unsigned int size,
11068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 const struct nf_conntrack *ct,
11078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 unsigned int msg_type,
11088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 unsigned int out_type,
11098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 unsigned int flags,
11108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			 struct nfct_labelmap *map)
11118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
11128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __snprintf_conntrack(buf, size, ct, msg_type, out_type, flags, map);
11138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
11148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
11158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
11168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_compare - compare two conntrack objects
11178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct1 pointer to a valid conntrack object
11188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct2 pointer to a valid conntrack object
11198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function only compare attribute set in both objects, ie. if a certain
11218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * attribute is not set in ct1 but it is in ct2, then the value of such
11228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * attribute is not used in the comparison.
11238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If both conntrack object are equal, this function returns 1, otherwise
11258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
11268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NOTICE: The use nfct_cmp is preferred.
11288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
11298a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_compare(const struct nf_conntrack *ct1,
11308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		 const struct nf_conntrack *ct2)
11318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
11328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct1 != NULL);
11338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct2 != NULL);
11348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
11358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __compare(ct1, ct2, NFCT_CMP_ALL);
11368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
11378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
11388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
11398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_cmp - compare two conntrack objects
11408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct1 pointer to a valid conntrack object
11418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct2 pointer to a valid conntrack object
11428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags flags
11438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function only compare attribute set in both objects, by default
11458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the comparison is not strict, ie. if a certain attribute is not set in one
11468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * of the objects, then such attribute is not used in the comparison.
11478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If you want more strict comparisons, you can use the appropriate flags
11488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * to modify this behaviour (see NFCT_CMP_STRICT and NFCT_CMP_MASK).
11498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The available flags are:
11518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_STRICT: the compared objects must have the same attributes
11538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	and the same values, otherwise it returns that the objects are
11548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	different.
11558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_MASK: the first object is used as mask, this means that
11568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	if an attribute is present in ct1 but not in ct2, this function
11578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	returns that the objects are different.
11588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_ALL: full comparison of both objects
11598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_ORIG: it only compares the source and destination address;
11608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	source and destination ports; the layer 3 and 4 protocol numbers
11618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	of the original direction; and the id (if present).
11628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_REPL: like NFCT_CMP_REPL but it compares the flow
11638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	information that goes in the reply direction.
11648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_TIMEOUT_EQ: timeout(ct1) == timeout(ct2)
11658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_TIMEOUT_GT: timeout(ct1) > timeout(ct2)
11668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_TIMEOUT_LT: timeout(ct1) < timeout(ct2)
11678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_TIMEOUT_GE: timeout(ct1) >= timeout(ct2)
11688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CMP_TIMEOUT_LE: timeout(ct1) <= timeout(ct2)
11698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The status bits comparison is status(ct1) & status(ct2) == status(ct1).
11718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If both conntrack object are equal, this function returns 1, otherwise
11738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
11748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
11758a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_cmp(const struct nf_conntrack *ct1,
11768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	     const struct nf_conntrack *ct2,
11778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	     unsigned int flags)
11788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
11798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct1 != NULL);
11808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct2 != NULL);
11818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
11828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __compare(ct1, ct2, flags);
11838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
11848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
11858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
11868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_copy - copy part of one source object to another
11878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct1 destination object
11888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct2 source object
11898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags flags
11908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function copies one part of the source object to the target.
11928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * It behaves like clone but:
11938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 1) You have to pass an already allocated space for the target object
11958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 2) You can copy only a part of the source object to the target
11968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
11978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The current supported flags are:
11988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CP_ALL: that copies the object entirely.
11998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CP_ORIG and NFCT_CP_REPL: that can be used to copy the
12008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	information that identifies a flow in the original and the reply
12018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	direction. This information is usually composed of: source and
12028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	destination IP address; source and destination ports; layer 3
12038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	and 4 protocol number.
12048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFCT_CP_META: that copies the metainformation
12058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	(all the attributes >= ATTR_TCP_STATE)
12068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *	- NFCT_CP_OVERRIDE: changes the default behaviour of nfct_copy() since
12078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *	it overrides the destination object. After the copy, the destination
12088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *	is a clone of the origin. This flag provides faster copying.
12098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
12108a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_copy(struct nf_conntrack *ct1,
12118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	       const struct nf_conntrack *ct2,
12128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	       unsigned int flags)
12138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
12148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	int i;
12158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct1 != NULL);
12178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ct2 != NULL);
12188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (flags & NFCT_CP_OVERRIDE) {
12208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__copy_fast(ct1, ct2);
12218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return;
12228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
12238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (flags == NFCT_CP_ALL) {
12248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		for (i=0; i<ATTR_MAX; i++) {
12258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			if (test_bit(i, ct2->head.set)) {
12268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				assert(copy_attr_array[i]);
12278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				copy_attr_array[i](ct1, ct2);
12288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				set_bit(i, ct1->head.set);
12298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			}
12308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
12318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return;
12328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
12338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	static const int cp_orig_mask[] = {
12358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_IPV4_SRC,
12368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_IPV4_DST,
12378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_IPV6_SRC,
12388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_IPV6_DST,
12398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_PORT_SRC,
12408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_PORT_DST,
12418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ICMP_TYPE,
12428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ICMP_CODE,
12438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ICMP_ID,
12448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_L3PROTO,
12458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_ORIG_L4PROTO,
12468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	};
12478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	#define __CP_ORIG_MAX sizeof(cp_orig_mask)/sizeof(int)
12488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (flags & NFCT_CP_ORIG) {
12508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		for (i=0; i<__CP_ORIG_MAX; i++) {
12518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			if (test_bit(cp_orig_mask[i], ct2->head.set)) {
12528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				assert(copy_attr_array[i]);
12538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				copy_attr_array[cp_orig_mask[i]](ct1, ct2);
12548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				set_bit(cp_orig_mask[i], ct1->head.set);
12558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			}
12568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
12578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
12588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	static const int cp_repl_mask[] = {
12608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_IPV4_SRC,
12618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_IPV4_DST,
12628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_IPV6_SRC,
12638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_IPV6_DST,
12648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_PORT_SRC,
12658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_PORT_DST,
12668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_L3PROTO,
12678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		ATTR_REPL_L4PROTO,
12688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	};
12698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	#define __CP_REPL_MAX sizeof(cp_repl_mask)/sizeof(int)
12708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (flags & NFCT_CP_REPL) {
12728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		for (i=0; i<__CP_REPL_MAX; i++) {
12738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			if (test_bit(cp_repl_mask[i], ct2->head.set)) {
12748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				assert(copy_attr_array[i]);
12758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				copy_attr_array[cp_repl_mask[i]](ct1, ct2);
12768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				set_bit(cp_repl_mask[i], ct1->head.set);
12778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			}
12788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
12798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
12808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (flags & NFCT_CP_META) {
12828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		for (i=ATTR_TCP_STATE; i<ATTR_MAX; i++) {
12838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			if (test_bit(i, ct2->head.set)) {
12848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				assert(copy_attr_array[i]),
12858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				copy_attr_array[i](ct1, ct2);
12868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				set_bit(i, ct1->head.set);
12878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			}
12888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		}
12898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
12908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
12918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
12928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
12938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_copy_attr - copy an attribute of one source object to another
12948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct1 destination object
12958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ct2 source object
12968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags flags
12978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
12988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function copies one attribute (if present) to another object.
12998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
13008a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_copy_attr(struct nf_conntrack *ct1,
13018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		    const struct nf_conntrack *ct2,
13028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		    const enum nf_conntrack_attr type)
13038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
13048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (test_bit(type, ct2->head.set)) {
13058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		assert(copy_attr_array[type]);
13068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		copy_attr_array[type](ct1, ct2);
13078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_bit(type, ct1->head.set);
13088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
13098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
13108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
13128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
13138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
13148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
13168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup bsf Kernel-space filtering for events
13178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
13188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
13198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
13208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
13228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_create - create a filter
13238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
13248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function returns a valid pointer on success, otherwise NULL is
13258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returned and errno is appropriately set.
13268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
13278a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nfct_filter *nfct_filter_create(void)
13288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
13298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return calloc(sizeof(struct nfct_filter), 1);
13308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
13318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
13338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_destroy - destroy a filter
13348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter filter that we want to destroy
13358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
13368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function releases the memory that is used by the filter object.
13378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * However, please note that this function does *not* detach an already
13388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * attached filter.
13398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
13408a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_filter_destroy(struct nfct_filter *filter)
13418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
13428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(filter != NULL);
13438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(filter);
13448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	filter = NULL;
13458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
13468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
13488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_add_attr - add a filter attribute of the filter object
13498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter filter object that we want to modify
13508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type filter attribute type
13518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value pointer to the value of the filter attribute
13528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
13538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Limitations: You can add up to 127 IPv4 addresses and masks for
13548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFCT_FILTER_SRC_IPV4 and, similarly, 127 for NFCT_FILTER_DST_IPV4.
13558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
13568a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_filter_add_attr(struct nfct_filter *filter,
13578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			  const enum nfct_filter_attr type,
13588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			  const void *value)
13598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
13608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(filter != NULL);
13618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(value != NULL);
13628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= NFCT_FILTER_MAX))
13648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return;
13658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (filter_attr_array[type]) {
13678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		filter_attr_array[type](filter, value);
13688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_bit(type, filter->set);
13698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
13708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
13718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
13738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_add_attr_u32 - add an u32 filter attribute of the filter object
13748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter filter object that we want to modify
13758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type filter attribute type
13768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value value of the filter attribute using unsigned int (32 bits).
13778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
13788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Limitations: You can add up to 255 protocols which is a reasonable limit.
13798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
13808a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_filter_add_attr_u32(struct nfct_filter *filter,
13818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			      const enum nfct_filter_attr type,
13828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			      uint32_t value)
13838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
13848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_filter_add_attr(filter, type, &value);
13858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
13868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
13878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
13888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_set_logic - set the filter logic for an attribute type
13898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter filter object that we want to modify
13908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type filter attribute type
13918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param logic filter logic that we want to use
13928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
13938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * You can only use this function once to set the filtering logic for
13948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * one attribute. You can define two logics: NFCT_FILTER_LOGIC_POSITIVE
13958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * that accept events that match the filter, and NFCT_FILTER_LOGIC_NEGATIVE
13968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * that rejects events that match the filter. Default filtering logic is
13978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFCT_FILTER_LOGIC_POSITIVE.
13988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
13998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, it returns -1 and errno is appropriately set. On success, it
14008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returns 0.
14018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14028a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_filter_set_logic(struct nfct_filter *filter,
14038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			  const enum nfct_filter_attr type,
14048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			  const enum nfct_filter_logic logic)
14058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
14068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= NFCT_FILTER_MAX)) {
14078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = ENOTSUP;
14088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar                return -1;
14098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
14108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (filter->logic[type]) {
14128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EBUSY;
14138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
14148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
14158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	filter->logic[type] = logic;
14178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
14198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
14208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
14228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_attach - attach a filter to a socket descriptor
14238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param fd socket descriptor
14248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter filter that we want to attach to the socket
14258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
14268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function returns -1 on error and set errno appropriately. If the
14278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * function returns EINVAL probably you have found a bug in it. Please,
14288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * report this.
14298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14308a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_filter_attach(int fd, struct nfct_filter *filter)
14318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
14328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(filter != NULL);
14338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __setup_netlink_socket_filter(fd, filter);
14358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
14368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
14388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_detach - detach an existing filter
14398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param fd socket descriptor
14408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
14418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function returns -1 on error and set errno appropriately.
14428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14438a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_filter_detach(int fd)
14448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
14458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	int val = 0;
14468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val));
14488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
14498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
14518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
14528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
14558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup dumpfilter Kernel-space filtering for dumping
14568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
14578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
14588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
14618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_dump_create - create a dump filter
14628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
14638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function returns a valid pointer on success, otherwise NULL is
14648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returned and errno is appropriately set.
14658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14668a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nfct_filter_dump *nfct_filter_dump_create(void)
14678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
14688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return calloc(sizeof(struct nfct_filter_dump), 1);
14698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
14708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
14728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_dump_destroy - destroy a dump filter
14738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter filter that we want to destroy
14748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
14758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function releases the memory that is used by the filter object.
14768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14778a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_filter_dump_destroy(struct nfct_filter_dump *filter)
14788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
14798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(filter != NULL);
14808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(filter);
14818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	filter = NULL;
14828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
14838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
14858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_dump_attr_set - set filter attribute
14868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter dump filter object that we want to modify
14878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type filter attribute type
14888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value pointer to the value of the filter attribute
14898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
14908a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_filter_dump_set_attr(struct nfct_filter_dump *filter_dump,
14918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       const enum nfct_filter_dump_attr type,
14928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       const void *value)
14938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
14948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(filter_dump != NULL);
14958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(value != NULL);
14968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
14978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (unlikely(type >= NFCT_FILTER_DUMP_MAX))
14988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return;
14998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (set_filter_dump_attr_array[type]) {
15018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_filter_dump_attr_array[type](filter_dump, value);
15028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		filter_dump->set |= (1 << type);
15038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
15048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
15058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_filter_dump_attr_set_u8 - set u8 dump filter attribute
15088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param filter dump filter object that we want to modify
15098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type filter attribute type
15108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value value of the filter attribute using unsigned int (32 bits).
15118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15128a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_filter_dump_set_attr_u8(struct nfct_filter_dump *filter_dump,
15138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				  const enum nfct_filter_dump_attr type,
15148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				  uint8_t value)
15158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
15168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfct_filter_dump_set_attr(filter_dump, type, &value);
15178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
15188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
15218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup label Conntrack labels
15258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
15278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_labels_get_path - get name of default config path
15318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returns a pointer to a immutable (static) string containing
15338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the default connlabel.conf file location.
15348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15358a44513648da0c5f5551f96b329cf56b66f5b303pkanwarconst char *nfct_labels_get_path(void)
15368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
15378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __labels_get_path();
15388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
15398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_labelmap_get_name - get name of the label bit
15428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param m label map obtained from nfct_label_open
15448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param bit whose name should be returned
15458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returns a pointer to the name associated with the label.
15478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If no name has been configured, the empty string is returned.
15488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If bit is out of range, NULL is returned.
15498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15508a44513648da0c5f5551f96b329cf56b66f5b303pkanwarconst char *nfct_labelmap_get_name(struct nfct_labelmap *m, unsigned int bit)
15518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
15528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __labelmap_get_name(m, bit);
15538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
15548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_labelmap_get_bit - get bit associated with the name
15578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h label handle obtained from nfct_labelmap_new
15598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param name name of the label
15608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returns the bit associated with the name, or negative value on error.
15628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15638a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_labelmap_get_bit(struct nfct_labelmap *m, const char *name)
15648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
15658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __labelmap_get_bit(m, name);
15668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
15678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_labelmap_new - create a new label map
15708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param mapfile the file containing the bit <-> name mapping
15728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If mapfile is NULL, the default mapping file is used.
15748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returns a new label map, or NULL on error.
15758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15768a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nfct_labelmap *nfct_labelmap_new(const char *mapfile)
15778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
15788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __labelmap_new(mapfile);
15798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
15808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_labelmap_destroy - destroy nfct_labelmap object
15838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param map the label object to destroy.
15858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
15868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function releases the memory that is used by the labelmap object.
15878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15888a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_labelmap_destroy(struct nfct_labelmap *map)
15898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
15908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	__labelmap_destroy(map);
15918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
15928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
15948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
15958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
15968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
15978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
15988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup bitmask bitmask object
15998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
16018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
16028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
16048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_new - allocate a new bitmask
16058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param max highest valid bit that can be set/unset.
16078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * In case of success, this function returns a valid pointer to a memory blob,
16098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * otherwise NULL is returned and errno is set appropiately.
16108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
16118a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nfct_bitmask *nfct_bitmask_new(unsigned int max)
16128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
16138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfct_bitmask *b;
16148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int bytes, words;
16158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (max > 0xffff)
16178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
16188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	words = DIV_ROUND_UP(max+1, 32);
16208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	bytes = words * sizeof(b->bits[0]);
16218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	b = malloc(sizeof(*b) + bytes);
16238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (b) {
16248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		memset(b->bits, 0, bytes);
16258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		b->words = words;
16268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
16278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return b;
16288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
16298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
16318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_clone - duplicate a bitmask object
16328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b pointer to the bitmask object to duplicate
16348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returns an identical copy of the bitmask.
16368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
16378a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nfct_bitmask *nfct_bitmask_clone(const struct nfct_bitmask *b)
16388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
16398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int bytes = b->words * sizeof(b->bits[0]);
16408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfct_bitmask *copy;
16418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	bytes += sizeof(*b);
16438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	copy = malloc(bytes);
16458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (copy)
16468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		memcpy(copy, b, bytes);
16478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return copy;
16488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
16498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
16518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_set_bit - set bit in the bitmask
16528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b pointer to the bitmask object
16548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param bit the bit to set
16558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
16568a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_bitmask_set_bit(struct nfct_bitmask *b, unsigned int bit)
16578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
16588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int bits = b->words * 32;
16598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (bit < bits)
16608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_bit(bit, b->bits);
16618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
16628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
16648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_test_bit - test if a bit in the bitmask is set
16658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b pointer to the bitmask object
16678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param bit the bit to test
16688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * returns 0 if the bit is not set.
16708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
16718a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfct_bitmask_test_bit(const struct nfct_bitmask *b, unsigned int bit)
16728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
16738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int bits = b->words * 32;
16748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return bit < bits && test_bit(bit, b->bits);
16758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
16768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
16788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_unset_bit - unset bit in the bitmask
16798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b pointer to the bitmask object
16818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param bit the bit to clear
16828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
16838a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_bitmask_unset_bit(struct nfct_bitmask *b, unsigned int bit)
16848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
16858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int bits = b->words * 32;
16868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (bit < bits)
16878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		unset_bit(bit, b->bits);
16888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
16898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
16908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
16918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_maxbit - return highest bit that may be set/unset
16928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
16938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b pointer to the bitmask object
16948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
16958a44513648da0c5f5551f96b329cf56b66f5b303pkanwarunsigned int nfct_bitmask_maxbit(const struct nfct_bitmask *b)
16968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
16978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return (b->words * 32) - 1;
16988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
16998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
17008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
17018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_destroy - destroy bitmask object
17028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
17038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b pointer to the bitmask object
17048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
17058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function releases the memory that is used by the bitmask object.
17068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
17078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If you assign a bitmask object to a nf_conntrack object using
17088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_set_attr ATTR_CONNLABEL, then the ownership of the bitmask
17098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * object passes on to the nf_conntrack object. The nfct_bitmask object
17108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * will be destroyed when the nf_conntrack object is destroyed.
17118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
17128a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_bitmask_destroy(struct nfct_bitmask *b)
17138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
17148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(b);
17158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
17168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
17178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
17188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_clear - clear a bitmask object
17198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
17208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b pointer to the bitmask object to clear
17218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
17228a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfct_bitmask_clear(struct nfct_bitmask *b)
17238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
17248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int bytes = b->words * sizeof(b->bits[0]);
17258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(b->bits, 0, bytes);
17268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
17278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
17288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
17298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfct_bitmask_equal - compare two bitmask objects
17308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
17318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b1 pointer to a valid bitmask object
17328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param b2 pointer to a valid bitmask object
17338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
17348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If both bitmask object are equal, this function returns true, otherwise
17358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * false is returned.
17368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
17378a44513648da0c5f5551f96b329cf56b66f5b303pkanwarbool nfct_bitmask_equal(const struct nfct_bitmask *b1, const struct nfct_bitmask *b2)
17388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
17398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (b1->words != b2->words)
17408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return false;
17418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
17428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return memcmp(b1->bits, b2->bits, b1->words * sizeof(b1->bits[0])) == 0;
17438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
17448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
17458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
17468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
17478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1748