14#include <libmnl/libmnl.h>
16#include "internal/internal.h"
31 struct nf_expect *exp;
33 exp = malloc(
sizeof(
struct nf_expect));
37 memset(exp, 0,
sizeof(
struct nf_expect));
79 return sizeof(
struct nf_expect);
91 struct nf_expect *clone;
97 memcpy(clone, exp,
sizeof(*exp));
127int nfexp_cmp(
const struct nf_expect *exp1,
const struct nf_expect *exp2,
130 assert(exp1 != NULL);
131 assert(exp2 != NULL);
133 return __cmp_expect(exp1, exp2, flags);
159 enum nf_conntrack_msg_type type,
160 int (*cb)(
enum nf_conntrack_msg_type type,
161 struct nf_expect *exp,
165 struct __data_container *container;
169 container = malloc(
sizeof(
struct __data_container));
172 memset(container, 0,
sizeof(
struct __data_container));
176 container->type = type;
177 container->data = data;
179 h->nfnl_cb_exp.call = __callback;
180 h->nfnl_cb_exp.data = container;
181 h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX;
183 nfnl_callback_register(h->nfnlssh_exp,
187 nfnl_callback_register(h->nfnlssh_exp,
188 IPCTNL_MSG_EXP_DELETE,
202 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW);
203 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE);
206 free(h->nfnl_cb_exp.data);
208 h->nfnl_cb_exp.call = NULL;
209 h->nfnl_cb_exp.data = NULL;
210 h->nfnl_cb_exp.attr_count = 0;
233 enum nf_conntrack_msg_type type,
234 int (*cb)(
const struct nlmsghdr *nlh,
235 enum nf_conntrack_msg_type type,
236 struct nf_expect *exp,
240 struct __data_container *container;
244 container = malloc(
sizeof(
struct __data_container));
247 memset(container, 0,
sizeof(
struct __data_container));
251 container->type = type;
252 container->data = data;
254 h->nfnl_cb_exp.call = __callback;
255 h->nfnl_cb_exp.data = container;
256 h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX;
258 nfnl_callback_register(h->nfnlssh_exp,
262 nfnl_callback_register(h->nfnlssh_exp,
263 IPCTNL_MSG_EXP_DELETE,
277 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW);
278 nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE);
280 h->expect_cb2 = NULL;
281 free(h->nfnl_cb_exp.data);
283 h->nfnl_cb_exp.call = NULL;
284 h->nfnl_cb_exp.data = NULL;
285 h->nfnl_cb_exp.attr_count = 0;
310 const enum nf_expect_attr type,
314 assert(value != NULL);
316 if (type >= ATTR_EXP_MAX)
319 if (set_exp_attr_array[type]) {
320 set_exp_attr_array[type](exp, value);
321 set_bit(type, exp->set);
332 const enum nf_expect_attr type,
345 const enum nf_expect_attr type,
358 const enum nf_expect_attr type,
373 const enum nf_expect_attr type)
377 if (type >= ATTR_EXP_MAX) {
382 if (!test_bit(type, exp->set)) {
387 return get_exp_attr_array[type](exp);
400 const enum nf_expect_attr type)
403 return ret == NULL ? 0 : *ret;
416 const enum nf_expect_attr type)
419 return ret == NULL ? 0 : *ret;
432 const enum nf_expect_attr type)
435 return ret == NULL ? 0 : *ret;
447 const enum nf_expect_attr type)
451 if (type >= ATTR_EXP_MAX) {
455 return test_bit(type, exp->set);
467 const enum nf_expect_attr type)
471 if (type >= ATTR_EXP_MAX) {
475 unset_bit(type, exp->set);
510 const struct nf_expect *exp)
516 memset(req, 0, size);
518 return __build_expect(req, size, type, flags, exp);
521static void nfexp_fill_hdr(
struct nfnlhdr *req, uint16_t type, uint16_t flags,
522 uint8_t l3num, uint8_t version)
524 char *buf = (
char *)&req->nlh;
525 struct nlmsghdr *nlh;
526 struct nfgenmsg *nfh;
528 nlh = mnl_nlmsg_put_header(buf);
529 nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK_EXP << 8) | type;
530 nlh->nlmsg_flags = NLM_F_REQUEST | flags;
533 nfh = mnl_nlmsg_put_extra_header(nlh,
sizeof(
struct nfgenmsg));
534 nfh->nfgen_family = l3num;
535 nfh->version = version;
540__build_query_exp(
const enum nf_conntrack_query qt,
541 const void *data,
void *buffer,
unsigned int size)
543 struct nfnlhdr *req = buffer;
544 const uint8_t *family = data;
546 assert(data != NULL);
549 memset(buffer, 0, size);
553 __build_expect(req, size, IPCTNL_MSG_EXP_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data);
555 case NFCT_Q_CREATE_UPDATE:
556 __build_expect(req, size, IPCTNL_MSG_EXP_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK, data);
559 __build_expect(req, size, IPCTNL_MSG_EXP_GET, NLM_F_REQUEST|NLM_F_ACK, data);
562 __build_expect(req, size, IPCTNL_MSG_EXP_DELETE, NLM_F_REQUEST|NLM_F_ACK, data);
565 nfexp_fill_hdr(req, IPCTNL_MSG_EXP_DELETE, NLM_F_ACK, *family,
569 nfexp_fill_hdr(req, IPCTNL_MSG_EXP_GET, NLM_F_DUMP, *family,
610 const enum nf_conntrack_query qt,
615 return __build_query_exp(qt, data, buffer, size);
618static int __parse_expect_message_type(
const struct nlmsghdr *nlh)
620 uint16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
621 uint16_t flags = nlh->nlmsg_flags;
622 int ret = NFCT_T_UNKNOWN;
624 if (type == IPCTNL_MSG_EXP_NEW) {
625 if (flags & (NLM_F_CREATE|NLM_F_EXCL))
629 }
else if (type == IPCTNL_MSG_EXP_DELETE)
630 ret = NFCT_T_DESTROY;
660 const struct nlmsghdr *nlh,
661 struct nf_expect *exp)
668 flags = __parse_expect_message_type(nlh);
672 nfexp_nlmsg_parse(nlh, exp);
696 const enum nf_conntrack_query qt,
699 const size_t size = 4096;
706 assert(data != NULL);
708 if (__build_query_exp(qt, data, &u.req, size) == -1)
711 return nfnl_query(h->nfnlh, &u.req.nlh);
728 const enum nf_conntrack_query qt,
731 const size_t size = 4096;
738 assert(data != NULL);
740 if (__build_query_exp(qt, data, &u.req, size) == -1)
743 return nfnl_send(h->nfnlh, &u.req.nlh);
764 return nfnl_catch(h->nfnlh);
804 const struct nf_expect *exp,
805 unsigned int msg_type,
806 unsigned int out_type,
813 return __snprintf_expect(buf, size, exp, msg_type, out_type, flags);
void nfexp_callback_unregister(struct nfct_handle *h)
void nfexp_callback_unregister2(struct nfct_handle *h)
int nfexp_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_expect *exp, void *data), void *data)
int nfexp_callback_register(struct nfct_handle *h, enum nf_conntrack_msg_type type, int(*cb)(enum nf_conntrack_msg_type type, struct nf_expect *exp, void *data), void *data)
int nfexp_catch(struct nfct_handle *h)
int nfexp_send(struct nfct_handle *h, const enum nf_conntrack_query qt, const void *data)
int nfexp_query(struct nfct_handle *h, const enum nf_conntrack_query qt, const void *data)
void nfexp_set_attr_u32(struct nf_expect *exp, const enum nf_expect_attr type, uint32_t value)
struct nf_expect * nfexp_new(void)
uint32_t nfexp_get_attr_u32(const struct nf_expect *exp, const enum nf_expect_attr type)
size_t nfexp_sizeof(const struct nf_expect *exp)
const void * nfexp_get_attr(const struct nf_expect *exp, const enum nf_expect_attr type)
void nfexp_set_attr_u16(struct nf_expect *exp, const enum nf_expect_attr type, uint16_t value)
void nfexp_set_attr(struct nf_expect *exp, const enum nf_expect_attr type, const void *value)
int nfexp_cmp(const struct nf_expect *exp1, const struct nf_expect *exp2, unsigned int flags)
uint16_t nfexp_get_attr_u16(const struct nf_expect *exp, const enum nf_expect_attr type)
void nfexp_set_attr_u8(struct nf_expect *exp, const enum nf_expect_attr type, uint8_t value)
uint8_t nfexp_get_attr_u8(const struct nf_expect *exp, const enum nf_expect_attr type)
int nfexp_snprintf(char *buf, unsigned int size, const struct nf_expect *exp, unsigned int msg_type, unsigned int out_type, unsigned int flags)
void nfexp_destroy(struct nf_expect *exp)
int nfexp_attr_unset(struct nf_expect *exp, const enum nf_expect_attr type)
struct nf_expect * nfexp_clone(const struct nf_expect *exp)
int nfexp_attr_is_set(const struct nf_expect *exp, const enum nf_expect_attr type)
size_t nfexp_maxsize(void)
int nfexp_build_query(struct nfnl_subsys_handle *ssh, const enum nf_conntrack_query qt, const void *data, void *buffer, unsigned int size)
int nfexp_build_expect(struct nfnl_subsys_handle *ssh, void *req, size_t size, uint16_t type, uint16_t flags, const struct nf_expect *exp)
int nfexp_parse_expect(enum nf_conntrack_msg_type type, const struct nlmsghdr *nlh, struct nf_expect *exp)