conntrack/api.c
/*
* (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <string.h> /* for memset */
#include <errno.h>
#include <assert.h>
#include <libmnl/libmnl.h>
#include "internal/internal.h"
struct nf_conntrack *nfct_new(void)
{
struct nf_conntrack *ct;
ct = malloc(sizeof(struct nf_conntrack));
if (!ct)
return NULL;
memset(ct, 0, sizeof(struct nf_conntrack));
return ct;
}
void nfct_destroy(struct nf_conntrack *ct)
{
assert(ct != NULL);
if (ct->secctx)
free(ct->secctx);
if (ct->helper_info)
free(ct->helper_info);
if (ct->connlabels)
nfct_bitmask_destroy(ct->connlabels);
if (ct->connlabels_mask)
nfct_bitmask_destroy(ct->connlabels_mask);
free(ct);
ct = NULL; /* bugtrap */
}
size_t nfct_sizeof(const struct nf_conntrack *ct)
{
assert(ct != NULL);
return sizeof(*ct);
}
size_t nfct_maxsize(void)
{
return sizeof(struct nf_conntrack);
}
struct nf_conntrack *nfct_clone(const struct nf_conntrack *ct)
{
struct nf_conntrack *clone;
assert(ct != NULL);
if ((clone = nfct_new()) == NULL)
return NULL;
nfct_copy(clone, ct, NFCT_CP_OVERRIDE);
return clone;
}
int nfct_setobjopt(struct nf_conntrack *ct, unsigned int option)
{
assert(ct != NULL);
if (unlikely(option > NFCT_SOPT_MAX)) {
errno = EOPNOTSUPP;
return -1;
}
return __setobjopt(ct, option);
}
int nfct_getobjopt(const struct nf_conntrack *ct, unsigned int option)
{
assert(ct != NULL);
if (unlikely(option > NFCT_GOPT_MAX)) {
errno = EOPNOTSUPP;
return -1;
}
return __getobjopt(ct, option);
}
int nfct_callback_register(struct nfct_handle *h,
enum nf_conntrack_msg_type type,
int (*cb)(enum nf_conntrack_msg_type type,
struct nf_conntrack *ct,
void *data),
void *data)
{
struct __data_container *container;
assert(h != NULL);
container = malloc(sizeof(struct __data_container));
if (!container)
return -1;
memset(container, 0, sizeof(struct __data_container));
h->cb = cb;
container->h = h;
container->type = type;
container->data = data;
h->nfnl_cb_ct.call = __callback;
h->nfnl_cb_ct.data = container;
h->nfnl_cb_ct.attr_count = CTA_MAX;
nfnl_callback_register(h->nfnlssh_ct,
IPCTNL_MSG_CT_NEW,
&h->nfnl_cb_ct);
nfnl_callback_register(h->nfnlssh_ct,
IPCTNL_MSG_CT_DELETE,
&h->nfnl_cb_ct);
return 0;
}
void nfct_callback_unregister(struct nfct_handle *h)
{
assert(h != NULL);
nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
h->cb = NULL;
free(h->nfnl_cb_ct.data);
h->nfnl_cb_ct.call = NULL;
h->nfnl_cb_ct.data = NULL;
h->nfnl_cb_ct.attr_count = 0;
}
int nfct_callback_register2(struct nfct_handle *h,
enum nf_conntrack_msg_type type,
int (*cb)(const struct nlmsghdr *nlh,
enum nf_conntrack_msg_type type,
struct nf_conntrack *ct,
void *data),
void *data)
{
struct __data_container *container;
assert(h != NULL);
container = calloc(1, sizeof(struct __data_container));
if (container == NULL)
return -1;
h->cb2 = cb;
container->h = h;
container->type = type;
container->data = data;
h->nfnl_cb_ct.call = __callback;
h->nfnl_cb_ct.data = container;
h->nfnl_cb_ct.attr_count = CTA_MAX;
nfnl_callback_register(h->nfnlssh_ct,
IPCTNL_MSG_CT_NEW,
&h->nfnl_cb_ct);
nfnl_callback_register(h->nfnlssh_ct,
IPCTNL_MSG_CT_DELETE,
&h->nfnl_cb_ct);
return 0;
}
void nfct_callback_unregister2(struct nfct_handle *h)
{
assert(h != NULL);
nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
h->cb2 = NULL;
free(h->nfnl_cb_ct.data);
h->nfnl_cb_ct.call = NULL;
h->nfnl_cb_ct.data = NULL;
h->nfnl_cb_ct.attr_count = 0;
}
void
nfct_set_attr_l(struct nf_conntrack *ct, const enum nf_conntrack_attr type,
const void *value, size_t len)
{
assert(ct != NULL);
assert(value != NULL);
if (unlikely(type >= ATTR_MAX))
return;
if (set_attr_array[type]) {
set_attr_array[type](ct, value, len);
set_bit(type, ct->head.set);
}
}
void nfct_set_attr(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
const void *value)
{
/* We assume the setter knows the size of the passed pointer. */
nfct_set_attr_l(ct, type, value, 0);
}
void nfct_set_attr_u8(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
uint8_t value)
{
nfct_set_attr_l(ct, type, &value, sizeof(uint8_t));
}
void nfct_set_attr_u16(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
uint16_t value)
{
nfct_set_attr_l(ct, type, &value, sizeof(uint16_t));
}
void nfct_set_attr_u32(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
uint32_t value)
{
nfct_set_attr_l(ct, type, &value, sizeof(uint32_t));
}
void nfct_set_attr_u64(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
uint64_t value)
{
nfct_set_attr_l(ct, type, &value, sizeof(uint64_t));
}
const void *nfct_get_attr(const struct nf_conntrack *ct,
const enum nf_conntrack_attr type)
{
assert(ct != NULL);
if (unlikely(type >= ATTR_MAX)) {
errno = EINVAL;
return NULL;
}
if (!test_bit(type, ct->head.set)) {
errno = ENODATA;
return NULL;
}
assert(get_attr_array[type]);
return get_attr_array[type](ct);
}
uint8_t nfct_get_attr_u8(const struct nf_conntrack *ct,
const enum nf_conntrack_attr type)
{
const uint8_t *ret = nfct_get_attr(ct, type);
return ret == NULL ? 0 : *ret;
}
uint16_t nfct_get_attr_u16(const struct nf_conntrack *ct,
const enum nf_conntrack_attr type)
{
const uint16_t *ret = nfct_get_attr(ct, type);
return ret == NULL ? 0 : *ret;
}
uint32_t nfct_get_attr_u32(const struct nf_conntrack *ct,
const enum nf_conntrack_attr type)
{
const uint32_t *ret = nfct_get_attr(ct, type);
return ret == NULL ? 0 : *ret;
}
uint64_t nfct_get_attr_u64(const struct nf_conntrack *ct,
const enum nf_conntrack_attr type)
{
const uint64_t *ret = nfct_get_attr(ct, type);
return ret == NULL ? 0 : *ret;
}
int nfct_attr_is_set(const struct nf_conntrack *ct,
const enum nf_conntrack_attr type)
{
assert(ct != NULL);
if (unlikely(type >= ATTR_MAX)) {
errno = EINVAL;
return -1;
}
return test_bit(type, ct->head.set);
}
int nfct_attr_is_set_array(const struct nf_conntrack *ct,
const enum nf_conntrack_attr *type_array,
int size)
{
int i;
assert(ct != NULL);
for (i=0; i<size; i++) {
if (unlikely(type_array[i] >= ATTR_MAX)) {
errno = EINVAL;
return -1;
}
if (!test_bit(type_array[i], ct->head.set))
return 0;
}
return 1;
}
int nfct_attr_unset(struct nf_conntrack *ct,
const enum nf_conntrack_attr type)
{
assert(ct != NULL);
if (unlikely(type >= ATTR_MAX)) {
errno = EINVAL;
return -1;
}
unset_bit(type, ct->head.set);
return 0;
}
void nfct_set_attr_grp(struct nf_conntrack *ct,
const enum nf_conntrack_attr_grp type,
const void *data)
{
assert(ct != NULL);
if (unlikely(type >= ATTR_GRP_MAX))
return;
if (set_attr_grp_array[type]) {
set_attr_grp_array[type](ct, data);
set_bitmask_u32(ct->head.set,
attr_grp_bitmask[type].bitmask, __NFCT_BITSET);
}
}
int nfct_get_attr_grp(const struct nf_conntrack *ct,
const enum nf_conntrack_attr_grp type,
void *data)
{
assert(ct != NULL);
if (unlikely(type >= ATTR_GRP_MAX)) {
errno = EINVAL;
return -1;
}
switch(attr_grp_bitmask[type].type) {
case NFCT_BITMASK_AND:
if (!test_bitmask_u32(ct->head.set,
attr_grp_bitmask[type].bitmask,
__NFCT_BITSET)) {
errno = ENODATA;
return -1;
}
break;
case NFCT_BITMASK_OR:
if (!test_bitmask_u32_or(ct->head.set,
attr_grp_bitmask[type].bitmask,
__NFCT_BITSET)) {
errno = ENODATA;
return -1;
}
break;
}
assert(get_attr_grp_array[type]);
get_attr_grp_array[type](ct, data);
return 0;
}
int nfct_attr_grp_is_set(const struct nf_conntrack *ct,
const enum nf_conntrack_attr_grp type)
{
assert(ct != NULL);
if (unlikely(type >= ATTR_GRP_MAX)) {
errno = EINVAL;
return -1;
}
switch(attr_grp_bitmask[type].type) {
case NFCT_BITMASK_AND:
if (test_bitmask_u32(ct->head.set,
attr_grp_bitmask[type].bitmask,
__NFCT_BITSET)) {
return 1;
}
break;
case NFCT_BITMASK_OR:
if (test_bitmask_u32_or(ct->head.set,
attr_grp_bitmask[type].bitmask,
__NFCT_BITSET)) {
return 1;
}
break;
}
return 0;
}
int nfct_attr_grp_unset(struct nf_conntrack *ct,
const enum nf_conntrack_attr_grp type)
{
assert(ct != NULL);
if (unlikely(type >= ATTR_GRP_MAX)) {
errno = EINVAL;
return -1;
}
unset_bitmask_u32(ct->head.set, attr_grp_bitmask[type].bitmask,
__NFCT_BITSET);
return 0;
}
int nfct_build_conntrack(struct nfnl_subsys_handle *ssh,
void *req,
size_t size,
uint16_t type,
uint16_t flags,
const struct nf_conntrack *ct)
{
assert(ssh != NULL);
assert(req != NULL);
assert(ct != NULL);
memset(req, 0, size);
return __build_conntrack(req, size, type, flags, ct);
}
static void nfct_fill_hdr(struct nfnlhdr *req, uint16_t type, uint16_t flags,
uint8_t l3num, uint8_t version)
{
char *buf = (char *)&req->nlh;
struct nlmsghdr *nlh;
struct nfgenmsg *nfh;
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | type;
nlh->nlmsg_flags = NLM_F_REQUEST | flags;
nlh->nlmsg_seq = 0;
nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
nfh->nfgen_family = l3num;
nfh->version = version;
nfh->res_id = 0;
}
static int
__build_query_ct(const enum nf_conntrack_query qt,
const void *data, void *buffer, unsigned int size)
{
struct nfnlhdr *req = buffer;
const uint32_t *family = data;
assert(data != NULL);
assert(req != NULL);
memset(buffer, 0, size);
switch(qt) {
case NFCT_Q_CREATE:
__build_conntrack(req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data);
break;
case NFCT_Q_UPDATE:
__build_conntrack(req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_ACK, data);
break;
case NFCT_Q_DESTROY:
__build_conntrack(req, size, IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST|NLM_F_ACK, data);
break;
case NFCT_Q_GET:
__build_conntrack(req, size, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_ACK, data);
break;
case NFCT_Q_FLUSH:
nfct_fill_hdr(req, IPCTNL_MSG_CT_DELETE, NLM_F_ACK, *family,
NFNETLINK_V0);
break;
case NFCT_Q_FLUSH_FILTER:
nfct_fill_hdr(req, IPCTNL_MSG_CT_DELETE, NLM_F_ACK, *family, 1);
if (__build_filter_flush(req, size, data) < 0)
return -1;
break;
case NFCT_Q_DUMP:
nfct_fill_hdr(req, IPCTNL_MSG_CT_GET, NLM_F_DUMP, *family,
NFNETLINK_V0);
break;
case NFCT_Q_DUMP_RESET:
nfct_fill_hdr(req, IPCTNL_MSG_CT_GET_CTRZERO, NLM_F_DUMP,
*family, NFNETLINK_V0);
break;
case NFCT_Q_CREATE_UPDATE:
__build_conntrack(req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK, data);
break;
case NFCT_Q_DUMP_FILTER:
nfct_fill_hdr(req, IPCTNL_MSG_CT_GET, NLM_F_DUMP, AF_UNSPEC,
NFNETLINK_V0);
if (__build_filter_dump(req, size, data) < 0)
return -1;
break;
case NFCT_Q_DUMP_FILTER_RESET:
nfct_fill_hdr(req, IPCTNL_MSG_CT_GET_CTRZERO, NLM_F_DUMP,
AF_UNSPEC, NFNETLINK_V0);
if (__build_filter_dump(req, size, data) < 0)
return -1;
break;
default:
errno = ENOTSUP;
return -1;
}
return 1;
}
int nfct_build_query(struct nfnl_subsys_handle *ssh,
const enum nf_conntrack_query qt,
const void *data,
void *buffer,
unsigned int size)
{
return __build_query_ct(qt, data, buffer, size);
}
static int __parse_message_type(const struct nlmsghdr *nlh)
{
uint16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
uint16_t flags = nlh->nlmsg_flags;
int ret = NFCT_T_UNKNOWN;
if (type == IPCTNL_MSG_CT_NEW) {
if (flags & (NLM_F_CREATE|NLM_F_EXCL))
ret = NFCT_T_NEW;
else
ret = NFCT_T_UPDATE;
} else if (type == IPCTNL_MSG_CT_DELETE)
ret = NFCT_T_DESTROY;
return ret;
}
int nfct_parse_conntrack(enum nf_conntrack_msg_type type,
const struct nlmsghdr *nlh,
struct nf_conntrack *ct)
{
unsigned int flags;
assert(nlh != NULL);
assert(ct != NULL);
flags = __parse_message_type(nlh);
if (!(flags & type))
return 0;
nfct_nlmsg_parse(nlh, ct);
return flags;
}
int nfct_query(struct nfct_handle *h,
const enum nf_conntrack_query qt,
const void *data)
{
const size_t size = 4096; /* enough for now */
union {
char buffer[size];
struct nfnlhdr req;
} u;
assert(h != NULL);
assert(data != NULL);
if (__build_query_ct(qt, data, &u.req, size) == -1)
return -1;
return nfnl_query(h->nfnlh, &u.req.nlh);
}
int nfct_send(struct nfct_handle *h,
const enum nf_conntrack_query qt,
const void *data)
{
const size_t size = 4096; /* enough for now */
union {
char buffer[size];
struct nfnlhdr req;
} u;
assert(h != NULL);
assert(data != NULL);
if (__build_query_ct(qt, data, &u.req, size) == -1)
return -1;
return nfnl_send(h->nfnlh, &u.req.nlh);
}
int nfct_catch(struct nfct_handle *h)
{
assert(h != NULL);
return nfnl_catch(h->nfnlh);
}
int nfct_snprintf(char *buf,
unsigned int size,
const struct nf_conntrack *ct,
unsigned int msg_type,
unsigned int out_type,
unsigned int flags)
{
assert(buf != NULL);
assert(size > 0);
assert(ct != NULL);
return __snprintf_conntrack(buf, size, ct, msg_type, out_type, flags, NULL);
}
int nfct_snprintf_labels(char *buf,
unsigned int size,
const struct nf_conntrack *ct,
unsigned int msg_type,
unsigned int out_type,
unsigned int flags,
struct nfct_labelmap *map)
{
return __snprintf_conntrack(buf, size, ct, msg_type, out_type, flags, map);
}
int nfct_compare(const struct nf_conntrack *ct1,
const struct nf_conntrack *ct2)
{
assert(ct1 != NULL);
assert(ct2 != NULL);
return __compare(ct1, ct2, NFCT_CMP_ALL);
}
int nfct_cmp(const struct nf_conntrack *ct1,
const struct nf_conntrack *ct2,
unsigned int flags)
{
assert(ct1 != NULL);
assert(ct2 != NULL);
return __compare(ct1, ct2, flags);
}
void nfct_copy(struct nf_conntrack *ct1,
const struct nf_conntrack *ct2,
unsigned int flags)
{
int i;
assert(ct1 != NULL);
assert(ct2 != NULL);
if (flags & NFCT_CP_OVERRIDE) {
__copy_fast(ct1, ct2);
return;
}
if (flags == NFCT_CP_ALL) {
for (i=0; i<ATTR_MAX; i++) {
if (test_bit(i, ct2->head.set)) {
assert(copy_attr_array[i]);
copy_attr_array[i](ct1, ct2);
set_bit(i, ct1->head.set);
}
}
return;
}
static const int cp_orig_mask[] = {
ATTR_ORIG_IPV4_SRC,
ATTR_ORIG_IPV4_DST,
ATTR_ORIG_IPV6_SRC,
ATTR_ORIG_IPV6_DST,
ATTR_ORIG_PORT_SRC,
ATTR_ORIG_PORT_DST,
ATTR_ICMP_TYPE,
ATTR_ICMP_CODE,
ATTR_ICMP_ID,
ATTR_ORIG_L3PROTO,
ATTR_ORIG_L4PROTO,
};
#define __CP_ORIG_MAX sizeof(cp_orig_mask)/sizeof(int)
if (flags & NFCT_CP_ORIG) {
for (i=0; i<__CP_ORIG_MAX; i++) {
if (test_bit(cp_orig_mask[i], ct2->head.set)) {
assert(copy_attr_array[i]);
copy_attr_array[cp_orig_mask[i]](ct1, ct2);
set_bit(cp_orig_mask[i], ct1->head.set);
}
}
}
static const int cp_repl_mask[] = {
ATTR_REPL_IPV4_SRC,
ATTR_REPL_IPV4_DST,
ATTR_REPL_IPV6_SRC,
ATTR_REPL_IPV6_DST,
ATTR_REPL_PORT_SRC,
ATTR_REPL_PORT_DST,
ATTR_REPL_L3PROTO,
ATTR_REPL_L4PROTO,
};
#define __CP_REPL_MAX sizeof(cp_repl_mask)/sizeof(int)
if (flags & NFCT_CP_REPL) {
for (i=0; i<__CP_REPL_MAX; i++) {
if (test_bit(cp_repl_mask[i], ct2->head.set)) {
assert(copy_attr_array[i]);
copy_attr_array[cp_repl_mask[i]](ct1, ct2);
set_bit(cp_repl_mask[i], ct1->head.set);
}
}
}
if (flags & NFCT_CP_META) {
for (i=ATTR_TCP_STATE; i<ATTR_MAX; i++) {
if (test_bit(i, ct2->head.set)) {
assert(copy_attr_array[i]),
copy_attr_array[i](ct1, ct2);
set_bit(i, ct1->head.set);
}
}
}
}
void nfct_copy_attr(struct nf_conntrack *ct1,
const struct nf_conntrack *ct2,
const enum nf_conntrack_attr type)
{
if (test_bit(type, ct2->head.set)) {
assert(copy_attr_array[type]);
copy_attr_array[type](ct1, ct2);
set_bit(type, ct1->head.set);
}
}
struct nfct_filter *nfct_filter_create(void)
{
return calloc(1, sizeof(struct nfct_filter));
}
void nfct_filter_destroy(struct nfct_filter *filter)
{
assert(filter != NULL);
free(filter);
filter = NULL;
}
void nfct_filter_add_attr(struct nfct_filter *filter,
const enum nfct_filter_attr type,
const void *value)
{
assert(filter != NULL);
assert(value != NULL);
if (unlikely(type >= NFCT_FILTER_MAX))
return;
if (filter_attr_array[type]) {
filter_attr_array[type](filter, value);
set_bit(type, filter->set);
}
}
void nfct_filter_add_attr_u32(struct nfct_filter *filter,
const enum nfct_filter_attr type,
uint32_t value)
{
nfct_filter_add_attr(filter, type, &value);
}
int nfct_filter_set_logic(struct nfct_filter *filter,
const enum nfct_filter_attr type,
const enum nfct_filter_logic logic)
{
if (unlikely(type >= NFCT_FILTER_MAX)) {
errno = ENOTSUP;
return -1;
}
if (filter->logic[type]) {
errno = EBUSY;
return -1;
}
filter->logic[type] = logic;
return 0;
}
int nfct_filter_attach(int fd, struct nfct_filter *filter)
{
assert(filter != NULL);
return __setup_netlink_socket_filter(fd, filter);
}
int nfct_filter_detach(int fd)
{
int val = 0;
return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val));
}
struct nfct_filter_dump *nfct_filter_dump_create(void)
{
return calloc(1, sizeof(struct nfct_filter_dump));
}
void nfct_filter_dump_destroy(struct nfct_filter_dump *filter)
{
assert(filter != NULL);
free(filter);
filter = NULL;
}
void nfct_filter_dump_set_attr(struct nfct_filter_dump *filter_dump,
const enum nfct_filter_dump_attr type,
const void *value)
{
assert(filter_dump != NULL);
assert(value != NULL);
if (unlikely(type >= NFCT_FILTER_DUMP_MAX))
return;
if (set_filter_dump_attr_array[type]) {
set_filter_dump_attr_array[type](filter_dump, value);
filter_dump->set |= (1 << type);
}
}
void nfct_filter_dump_set_attr_u8(struct nfct_filter_dump *filter_dump,
const enum nfct_filter_dump_attr type,
uint8_t value)
{
nfct_filter_dump_set_attr(filter_dump, type, &value);
}
void nfct_filter_dump_set_attr_u16(struct nfct_filter_dump *filter_dump,
const enum nfct_filter_dump_attr type,
uint16_t value)
{
nfct_filter_dump_set_attr(filter_dump, type, &value);
}
const char *nfct_labels_get_path(void)
{
return __labels_get_path();
}
const char *nfct_labelmap_get_name(struct nfct_labelmap *m, unsigned int bit)
{
return __labelmap_get_name(m, bit);
}
int nfct_labelmap_get_bit(struct nfct_labelmap *m, const char *name)
{
return __labelmap_get_bit(m, name);
}
struct nfct_labelmap *nfct_labelmap_new(const char *mapfile)
{
return __labelmap_new(mapfile);
}
void nfct_labelmap_destroy(struct nfct_labelmap *map)
{
__labelmap_destroy(map);
}
/*
* \defgroup bitmask bitmask object
*
* @{
*/
struct nfct_bitmask *nfct_bitmask_new(unsigned int max)
{
struct nfct_bitmask *b;
unsigned int bytes, words;
if (max > 0xffff)
return NULL;
words = DIV_ROUND_UP(max+1, 32);
bytes = words * sizeof(b->bits[0]);
b = malloc(sizeof(*b) + bytes);
if (b) {
memset(b->bits, 0, bytes);
b->words = words;
}
return b;
}
/*
* nfct_bitmask_clone - duplicate a bitmask object
*
* \param b pointer to the bitmask object to duplicate
*
* returns an identical copy of the bitmask.
*/
struct nfct_bitmask *nfct_bitmask_clone(const struct nfct_bitmask *b)
{
unsigned int bytes = b->words * sizeof(b->bits[0]);
struct nfct_bitmask *copy;
bytes += sizeof(*b);
copy = malloc(bytes);
if (copy)
memcpy(copy, b, bytes);
return copy;
}
/*
* nfct_bitmask_set_bit - set bit in the bitmask
*
* \param b pointer to the bitmask object
* \param bit the bit to set
*/
void nfct_bitmask_set_bit(struct nfct_bitmask *b, unsigned int bit)
{
unsigned int bits = b->words * 32;
if (bit < bits)
set_bit(bit, b->bits);
}
/*
* nfct_bitmask_test_bit - test if a bit in the bitmask is set
*
* \param b pointer to the bitmask object
* \param bit the bit to test
*
* returns 0 if the bit is not set.
*/
int nfct_bitmask_test_bit(const struct nfct_bitmask *b, unsigned int bit)
{
unsigned int bits = b->words * 32;
return bit < bits && test_bit(bit, b->bits);
}
/*
* nfct_bitmask_unset_bit - unset bit in the bitmask
*
* \param b pointer to the bitmask object
* \param bit the bit to clear
*/
void nfct_bitmask_unset_bit(struct nfct_bitmask *b, unsigned int bit)
{
unsigned int bits = b->words * 32;
if (bit < bits)
unset_bit(bit, b->bits);
}
/*
* nfct_bitmask_maxbit - return highest bit that may be set/unset
*
* \param b pointer to the bitmask object
*/
unsigned int nfct_bitmask_maxbit(const struct nfct_bitmask *b)
{
return (b->words * 32) - 1;
}
/*
* nfct_bitmask_destroy - destroy bitmask object
*
* \param b pointer to the bitmask object
*
* This function releases the memory that is used by the bitmask object.
*
* If you assign a bitmask object to a nf_conntrack object using
* nfct_set_attr ATTR_CONNLABEL, then the ownership of the bitmask
* object passes on to the nf_conntrack object. The nfct_bitmask object
* will be destroyed when the nf_conntrack object is destroyed.
*/
void nfct_bitmask_destroy(struct nfct_bitmask *b)
{
free(b);
}
/*
* nfct_bitmask_clear - clear a bitmask object
*
* \param b pointer to the bitmask object to clear
*/
void nfct_bitmask_clear(struct nfct_bitmask *b)
{
unsigned int bytes = b->words * sizeof(b->bits[0]);
memset(b->bits, 0, bytes);
}
/*
* nfct_bitmask_equal - compare two bitmask objects
*
* \param b1 pointer to a valid bitmask object
* \param b2 pointer to a valid bitmask object
*
* If both bitmask object are equal, this function returns true, otherwise
* false is returned.
*/
bool nfct_bitmask_equal(const struct nfct_bitmask *b1, const struct nfct_bitmask *b2)
{
if (b1->words != b2->words)
return false;
return memcmp(b1->bits, b2->bits, b1->words * sizeof(b1->bits[0])) == 0;
}
nfct_callback_register
int nfct_callback_register(struct nfct_handle *h, enum nf_conntrack_msg_type type, int(*cb)(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data), void *data)
Definition conntrack/api.c:224
nfct_callback_unregister2
void nfct_callback_unregister2(struct nfct_handle *h)
Definition conntrack/api.c:338
nfct_callback_unregister
void nfct_callback_unregister(struct nfct_handle *h)
Definition conntrack/api.c:264
nfct_callback_register2
int nfct_callback_register2(struct nfct_handle *h, enum nf_conntrack_msg_type type, int(*cb)(const struct nlmsghdr *nlh, enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data), void *data)
Definition conntrack/api.c:298
nfct_filter_destroy
void nfct_filter_destroy(struct nfct_filter *filter)
Definition conntrack/api.c:1377
nfct_filter_detach
int nfct_filter_detach(int fd)
Definition conntrack/api.c:1480
nfct_filter_set_logic
int nfct_filter_set_logic(struct nfct_filter *filter, const enum nfct_filter_attr type, const enum nfct_filter_logic logic)
Definition conntrack/api.c:1439
nfct_filter_attach
int nfct_filter_attach(int fd, struct nfct_filter *filter)
Definition conntrack/api.c:1467
nfct_filter_add_attr_u32
void nfct_filter_add_attr_u32(struct nfct_filter *filter, const enum nfct_filter_attr type, uint32_t value)
Definition conntrack/api.c:1417
nfct_filter_add_attr
void nfct_filter_add_attr(struct nfct_filter *filter, const enum nfct_filter_attr type, const void *value)
Definition conntrack/api.c:1393
nfct_filter_create
struct nfct_filter * nfct_filter_create(void)
Definition conntrack/api.c:1364
nfct_send
int nfct_send(struct nfct_handle *h, const enum nf_conntrack_query qt, const void *data)
Definition conntrack/api.c:1023
nfct_catch
int nfct_catch(struct nfct_handle *h)
Definition conntrack/api.c:1057
nfct_query
int nfct_query(struct nfct_handle *h, const enum nf_conntrack_query qt, const void *data)
Definition conntrack/api.c:991
nfct_sizeof
size_t nfct_sizeof(const struct nf_conntrack *ct)
Definition conntrack/api.c:114
nfct_snprintf_labels
int nfct_snprintf_labels(char *buf, unsigned int size, const struct nf_conntrack *ct, unsigned int msg_type, unsigned int out_type, unsigned int flags, struct nfct_labelmap *map)
Definition conntrack/api.c:1141
nfct_set_attr_u32
void nfct_set_attr_u32(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint32_t value)
Definition conntrack/api.c:439
nfct_destroy
void nfct_destroy(struct nf_conntrack *ct)
Definition conntrack/api.c:93
nfct_copy_attr
void nfct_copy_attr(struct nf_conntrack *ct1, const struct nf_conntrack *ct2, const enum nf_conntrack_attr type)
Definition conntrack/api.c:1337
nfct_set_attr
void nfct_set_attr(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value)
Definition conntrack/api.c:399
nfct_attr_grp_unset
int nfct_attr_grp_unset(struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type)
Definition conntrack/api.c:731
nfct_get_attr_u64
uint64_t nfct_get_attr_u64(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
Definition conntrack/api.c:544
nfct_setobjopt
int nfct_setobjopt(struct nf_conntrack *ct, unsigned int option)
Definition conntrack/api.c:169
nfct_get_attr_grp
int nfct_get_attr_grp(const struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type, void *data)
Definition conntrack/api.c:655
nfct_set_attr_grp
void nfct_set_attr_grp(struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type, const void *data)
Definition conntrack/api.c:630
nfct_get_attr
const void * nfct_get_attr(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
Definition conntrack/api.c:467
nfct_attr_is_set_array
int nfct_attr_is_set_array(const struct nf_conntrack *ct, const enum nf_conntrack_attr *type_array, int size)
Definition conntrack/api.c:580
nfct_attr_unset
int nfct_attr_unset(struct nf_conntrack *ct, const enum nf_conntrack_attr type)
Definition conntrack/api.c:607
nfct_copy
void nfct_copy(struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags)
Definition conntrack/api.c:1247
nfct_get_attr_u16
uint16_t nfct_get_attr_u16(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
Definition conntrack/api.c:512
nfct_attr_grp_is_set
int nfct_attr_grp_is_set(const struct nf_conntrack *ct, const enum nf_conntrack_attr_grp type)
Definition conntrack/api.c:695
nfct_cmp
int nfct_cmp(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags)
Definition conntrack/api.c:1212
nfct_set_attr_u16
void nfct_set_attr_u16(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint16_t value)
Definition conntrack/api.c:426
nfct_get_attr_u32
uint32_t nfct_get_attr_u32(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
Definition conntrack/api.c:528
nfct_set_attr_u8
void nfct_set_attr_u8(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint8_t value)
Definition conntrack/api.c:413
nfct_set_attr_u64
void nfct_set_attr_u64(struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint64_t value)
Definition conntrack/api.c:452
nfct_set_attr_l
void nfct_set_attr_l(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value, size_t len)
Definition conntrack/api.c:370
nfct_snprintf
int nfct_snprintf(char *buf, unsigned int size, const struct nf_conntrack *ct, unsigned int msg_type, unsigned int out_type, unsigned int flags)
Definition conntrack/api.c:1113
nfct_maxsize
size_t nfct_maxsize(void)
Definition conntrack/api.c:136
nfct_attr_is_set
int nfct_attr_is_set(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
Definition conntrack/api.c:559
nfct_getobjopt
int nfct_getobjopt(const struct nf_conntrack *ct, unsigned int option)
Definition conntrack/api.c:189
nfct_compare
int nfct_compare(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2)
Definition conntrack/api.c:1166
nfct_get_attr_u8
uint8_t nfct_get_attr_u8(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
Definition conntrack/api.c:496
nfct_new
struct nf_conntrack * nfct_new(void)
Definition conntrack/api.c:76
nfct_clone
struct nf_conntrack * nfct_clone(const struct nf_conntrack *ct)
Definition conntrack/api.c:148
nfct_filter_dump_set_attr_u8
void nfct_filter_dump_set_attr_u8(struct nfct_filter_dump *filter_dump, const enum nfct_filter_dump_attr type, uint8_t value)
Definition conntrack/api.c:1549
nfct_filter_dump_create
struct nfct_filter_dump * nfct_filter_dump_create(void)
Definition conntrack/api.c:1503
nfct_filter_dump_destroy
void nfct_filter_dump_destroy(struct nfct_filter_dump *filter)
Definition conntrack/api.c:1514
nfct_filter_dump_set_attr_u16
void nfct_filter_dump_set_attr_u16(struct nfct_filter_dump *filter_dump, const enum nfct_filter_dump_attr type, uint16_t value)
Definition conntrack/api.c:1562
nfct_filter_dump_set_attr
void nfct_filter_dump_set_attr(struct nfct_filter_dump *filter_dump, const enum nfct_filter_dump_attr type, const void *value)
Definition conntrack/api.c:1527
nfct_labels_get_path
const char * nfct_labels_get_path(void)
Definition conntrack/api.c:1585
nfct_labelmap_destroy
void nfct_labelmap_destroy(struct nfct_labelmap *map)
Definition conntrack/api.c:1638
nfct_labelmap_get_name
const char * nfct_labelmap_get_name(struct nfct_labelmap *m, unsigned int bit)
Definition conntrack/api.c:1600
nfct_labelmap_new
struct nfct_labelmap * nfct_labelmap_new(const char *mapfile)
Definition conntrack/api.c:1626
nfct_labelmap_get_bit
int nfct_labelmap_get_bit(struct nfct_labelmap *m, const char *name)
Definition conntrack/api.c:1613
nfct_parse_conntrack
int nfct_parse_conntrack(enum nf_conntrack_msg_type type, const struct nlmsghdr *nlh, struct nf_conntrack *ct)
Definition conntrack/api.c:955
nfct_build_conntrack
int nfct_build_conntrack(struct nfnl_subsys_handle *ssh, void *req, size_t size, uint16_t type, uint16_t flags, const struct nf_conntrack *ct)
Definition conntrack/api.c:771
nfct_build_query
int nfct_build_query(struct nfnl_subsys_handle *ssh, const enum nf_conntrack_query qt, const void *data, void *buffer, unsigned int size)
Definition conntrack/api.c:905
nfct_labelmap
Definition labels.c:17