18#include <libmnl/libmnl.h>
19#include <linux/netfilter/nfnetlink.h>
20#include <linux/netfilter/nfnetlink_cthelper.h>
22#include <libnetfilter_cthelper/libnetfilter_cthelper.h>
60#ifndef NF_CT_HELPER_NAME_MAX
61#define NF_CT_HELPER_NAME_MAX 16
64#ifndef NF_CT_HELPER_CLASS_MAX
65#define NF_CT_HELPER_CLASS_MAX 4
69 char name[NF_CT_HELPER_NAME_MAX];
70 uint32_t expect_timeout;
76 char name[NF_CT_HELPER_NAME_MAX];
77 uint32_t priv_data_len;
115 for (i=0; i<NF_CT_HELPER_CLASS_MAX; i++) {
116 if (h->expect_policy[i])
117 free(h->expect_policy[i]);
150 enum nfct_helper_policy_attr_type type,
154 case NFCTH_ATTR_POLICY_NAME:
155 strncpy(p->name, data, NF_CT_HELPER_NAME_MAX);
156 p->name[NF_CT_HELPER_NAME_MAX-1] =
'\0';
157 p->bitset |= (1 << NFCTH_ATTR_POLICY_NAME);
159 case NFCTH_ATTR_POLICY_TIMEOUT:
160 p->expect_timeout = *((uint32_t *) data);
161 p->bitset |= (1 << NFCTH_ATTR_POLICY_TIMEOUT);
163 case NFCTH_ATTR_POLICY_MAX:
164 p->expect_max = *((uint32_t *) data);
165 p->bitset |= (1 << NFCTH_ATTR_POLICY_MAX);
178 enum nfct_helper_policy_attr_type type,
186 enum nfct_helper_policy_attr_type type,
200 enum nfct_helper_attr_type type,
const void *data)
203 case NFCTH_ATTR_NAME:
204 strncpy(h->name, data, NF_CT_HELPER_NAME_MAX);
205 h->name[NF_CT_HELPER_NAME_MAX-1] =
'\0';
206 h->bitset |= (1 << NFCTH_ATTR_NAME);
208 case NFCTH_ATTR_QUEUE_NUM:
209 h->queue_num = *((uint32_t *) data);
210 h->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
212 case NFCTH_ATTR_PROTO_L3NUM:
213 h->tuple.l3num = *((uint16_t *) data);
214 h->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
216 case NFCTH_ATTR_PROTO_L4NUM:
217 h->tuple.l4num = *((uint8_t *) data);
218 h->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
220 case NFCTH_ATTR_PRIV_DATA_LEN:
221 h->priv_data_len = *((uint32_t *) data);
222 h->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
224 case NFCTH_ATTR_POLICY1:
226 h->bitset |= (1 << NFCTH_ATTR_POLICY1);
228 case NFCTH_ATTR_POLICY2:
230 h->bitset |= (1 << NFCTH_ATTR_POLICY2);
232 case NFCTH_ATTR_POLICY3:
234 h->bitset |= (1 << NFCTH_ATTR_POLICY3);
236 case NFCTH_ATTR_POLICY4:
238 h->bitset |= (1 << NFCTH_ATTR_POLICY4);
240 case NFCTH_ATTR_STATUS:
241 h->status = *((uint32_t *) data);
242 h->bitset |= (1 << NFCTH_ATTR_STATUS);
262 enum nfct_helper_attr_type type, uint8_t value)
269 enum nfct_helper_attr_type type, uint16_t value)
276 enum nfct_helper_attr_type type, uint32_t value)
290 case NFCTH_ATTR_NAME:
307const void __EXPORTED *
309 enum nfct_helper_attr_type type)
311 const void *ret = NULL;
314 case NFCTH_ATTR_NAME:
317 case NFCTH_ATTR_QUEUE_NUM:
318 ret = &helper->queue_num;
320 case NFCTH_ATTR_PROTO_L3NUM:
321 ret = &helper->tuple.l3num;
323 case NFCTH_ATTR_PROTO_L4NUM:
324 ret = &helper->tuple.l4num;
326 case NFCTH_ATTR_PRIV_DATA_LEN:
327 ret = &helper->priv_data_len;
329 case NFCTH_ATTR_POLICY1:
330 ret = helper->expect_policy[0];
332 case NFCTH_ATTR_POLICY2:
333 ret = helper->expect_policy[1];
335 case NFCTH_ATTR_POLICY3:
336 ret = helper->expect_policy[2];
338 case NFCTH_ATTR_POLICY4:
339 ret = helper->expect_policy[3];
341 case NFCTH_ATTR_STATUS:
342 ret = &helper->status;
358const char __EXPORTED *
360 enum nfct_helper_attr_type type)
375 enum nfct_helper_attr_type type)
390 enum nfct_helper_attr_type type)
405 enum nfct_helper_attr_type type)
423 unsigned int type,
unsigned int flags)
427 ret = snprintf(buf, size,
"{\n"
429 "\t.queuenum = %u,\n"
430 "\t.l3protonum = %u,\n"
431 "\t.l4protonum = %u,\n"
432 "\t.priv_data_len = %u,\n"
433 "\t.status = %s,\n};",
440 "enabled" :
"disabled");
479struct nlmsghdr __EXPORTED *
481 uint16_t flags, uint32_t seq)
483 struct nlmsghdr *nlh;
484 struct nfgenmsg *nfh;
486 nlh = mnl_nlmsg_put_header(buf);
487 nlh->nlmsg_type = (NFNL_SUBSYS_CTHELPER << 8) | cmd;
488 nlh->nlmsg_flags = NLM_F_REQUEST | flags;
489 nlh->nlmsg_seq = seq;
491 nfh = mnl_nlmsg_put_extra_header(nlh,
sizeof(
struct nfgenmsg));
492 nfh->nfgen_family = AF_UNSPEC;
493 nfh->version = NFNETLINK_V0;
500nfct_helper_nlmsg_build_policy(
struct nlmsghdr *nlh, uint16_t type,
505 nest = mnl_attr_nest_start(nlh, type);
506 mnl_attr_put_strz(nlh, NFCTH_POLICY_NAME, p->name);
507 mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_MAX, htonl(p->expect_max));
508 mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_TIMEOUT,
509 htonl(p->expect_timeout));
510 mnl_attr_nest_end(nlh, nest);
524 if (h->bitset & (1 << NFCTH_ATTR_NAME))
525 mnl_attr_put_strz(nlh, NFCTH_NAME, h->name);
527 if (h->bitset & (1 << NFCTH_ATTR_QUEUE_NUM))
528 mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(h->queue_num));
530 if (h->bitset & (1 << NFCTH_ATTR_PRIV_DATA_LEN)) {
531 mnl_attr_put_u32(nlh, NFCTH_PRIV_DATA_LEN,
532 htonl(h->priv_data_len));
535 if (h->bitset & (1 << NFCTH_ATTR_PROTO_L3NUM) ||
536 h->bitset & (1 << NFCTH_ATTR_PROTO_L4NUM)) {
537 nest = mnl_attr_nest_start(nlh, NFCTH_TUPLE);
538 mnl_attr_put_u16(nlh, NFCTH_TUPLE_L3PROTONUM,
539 htons(h->tuple.l3num));
540 mnl_attr_put_u8(nlh, NFCTH_TUPLE_L4PROTONUM, h->tuple.l4num);
541 mnl_attr_nest_end(nlh, nest);
544 if (h->bitset & (1 << NFCTH_ATTR_POLICY1) ||
545 h->bitset & (1 << NFCTH_ATTR_POLICY2) ||
546 h->bitset & (1 << NFCTH_ATTR_POLICY3) ||
547 h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
548 nest = mnl_attr_nest_start(nlh, NFCTH_POLICY);
549 int policy_set_num = 0;
551 if (h->bitset & (1 << NFCTH_ATTR_POLICY1)) {
552 nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET1,
553 h->expect_policy[0]);
556 if (h->bitset & (1 << NFCTH_ATTR_POLICY2)) {
557 nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET2,
558 h->expect_policy[1]);
561 if (h->bitset & (1 << NFCTH_ATTR_POLICY3)) {
562 nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET3,
563 h->expect_policy[2]);
566 if (h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
567 nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET4,
568 h->expect_policy[3]);
572 mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM,
573 htonl(policy_set_num));
575 mnl_attr_nest_end(nlh, nest);
578 if (h->bitset & (1 << NFCTH_ATTR_STATUS))
579 mnl_attr_put_u32(nlh, NFCTH_STATUS, ntohl(h->status));
583nfct_helper_nlmsg_parse_tuple_cb(
const struct nlattr *attr,
void *data)
585 const struct nlattr **tb = data;
586 int type = mnl_attr_get_type(attr);
588 if (mnl_attr_type_valid(attr, NFCTH_TUPLE_MAX) < 0)
592 case NFCTH_TUPLE_L3PROTONUM:
593 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
594 perror(
"mnl_attr_validate");
598 case NFCTH_TUPLE_L4PROTONUM:
599 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
600 perror(
"mnl_attr_validate");
612nfct_helper_nlmsg_parse_tuple(
const struct nlattr *attr,
615 struct nlattr *tb[NFCTH_TUPLE_MAX+1] = {};
617 mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_tuple_cb, tb);
618 if (tb[NFCTH_TUPLE_L3PROTONUM]) {
619 nfct_helper_attr_set_u16(helper, NFCTH_ATTR_PROTO_L3NUM,
620 ntohs(mnl_attr_get_u16(tb[NFCTH_TUPLE_L3PROTONUM])));
622 if (tb[NFCTH_TUPLE_L4PROTONUM]) {
623 nfct_helper_attr_set_u8(helper, NFCTH_ATTR_PROTO_L4NUM,
624 mnl_attr_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]));
629nfct_helper_nlmsg_parse_policy_cb(
const struct nlattr *attr,
void *data)
631 const struct nlattr **tb = data;
632 int type = mnl_attr_get_type(attr);
634 if (mnl_attr_type_valid(attr, NFCTH_POLICY_MAX) < 0)
638 case NFCTH_POLICY_NAME:
639 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
640 perror(
"mnl_attr_validate");
644 case NFCTH_POLICY_EXPECT_MAX:
645 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
646 perror(
"mnl_attr_validate");
650 case NFCTH_POLICY_EXPECT_TIMEOUT:
651 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
652 perror(
"mnl_attr_validate");
664nfct_helper_nlmsg_parse_policy_set_cb(
const struct nlattr *attr,
void *data)
666 const struct nlattr **tb = data;
667 int type = mnl_attr_get_type(attr);
669 if (mnl_attr_type_valid(attr, NFCTH_POLICY_SET_MAX) < 0)
673 case NFCTH_POLICY_SET_NUM:
674 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
675 perror(
"mnl_attr_validate");
688nfct_helper_nlmsg_parse_policy(
const struct nlattr *attr,
691 struct nlattr *tb[NFCTH_POLICY_MAX+1] = {};
698 mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_cb, tb);
699 if (tb[NFCTH_POLICY_NAME]) {
701 mnl_attr_get_str(tb[NFCTH_POLICY_NAME]));
703 if (tb[NFCTH_POLICY_EXPECT_MAX]) {
704 nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_MAX,
705 ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_MAX])));
707 if (tb[NFCTH_POLICY_EXPECT_TIMEOUT]) {
708 nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_TIMEOUT,
709 ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])));
712 helper->expect_policy[helper->policy_num++] = p;
716nfct_helper_nlmsg_parse_policy_set(
const struct nlattr *attr,
719 struct nlattr *tb[NFCTH_POLICY_SET_MAX+1] = {};
720 int i, policy_num = 0;
722 mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_set_cb, tb);
723 if (tb[NFCTH_POLICY_SET_NUM])
724 policy_num = ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_SET_NUM]));
726 for (i=0; i<policy_num; i++) {
727 if (tb[NFCTH_POLICY_SET+i]) {
728 nfct_helper_nlmsg_parse_policy(tb[NFCTH_POLICY_SET+i],
735nfct_helper_nlmsg_parse_attr_cb(
const struct nlattr *attr,
void *data)
737 const struct nlattr **tb = data;
738 int type = mnl_attr_get_type(attr);
740 if (mnl_attr_type_valid(attr, NFCTH_MAX) < 0)
745 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
746 perror(
"mnl_attr_validate");
750 case NFCTH_QUEUE_NUM:
751 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
752 perror(
"mnl_attr_validate");
757 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
758 perror(
"mnl_attr_validate");
763 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
764 perror(
"mnl_attr_validate");
785 struct nlattr *tb[NFCTH_MAX+1] = {};
786 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
788 mnl_attr_parse(nlh,
sizeof(*nfg), nfct_helper_nlmsg_parse_attr_cb, tb);
789 if (!tb[NFCTH_NAME] || !tb[NFCTH_QUEUE_NUM] ||
790 !tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_STATUS])
793 if (tb[NFCTH_NAME]) {
795 mnl_attr_get_str(tb[NFCTH_NAME]));
797 if (tb[NFCTH_ATTR_QUEUE_NUM]) {
798 nfct_helper_attr_set_u32(h, NFCTH_ATTR_QUEUE_NUM,
799 ntohl(mnl_attr_get_u32(tb[NFCTH_QUEUE_NUM])));
802 nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], h);
804 if (tb[NFCTH_POLICY])
805 nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], h);
807 if (tb[NFCTH_PRIV_DATA_LEN]) {
808 nfct_helper_attr_set_u32(h, NFCTH_ATTR_PRIV_DATA_LEN,
809 ntohl(mnl_attr_get_u32(tb[NFCTH_PRIV_DATA_LEN])));
812 if (tb[NFCTH_STATUS]) {
813 nfct_helper_attr_set_u32(h, NFCTH_ATTR_STATUS,
814 ntohl(mnl_attr_get_u32(tb[NFCTH_STATUS])));
const void __EXPORTED * nfct_helper_attr_get(struct nfct_helper *helper, enum nfct_helper_attr_type type)
void __EXPORTED nfct_helper_policy_attr_set_str(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const char *name)
uint32_t __EXPORTED nfct_helper_attr_get_u32(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void __EXPORTED nfct_helper_policy_free(struct nfct_helper_policy *p)
struct nfct_helper_policy __EXPORTED * nfct_helper_policy_alloc(void)
int __EXPORTED nfct_helper_snprintf(char *buf, size_t size, struct nfct_helper *helper, unsigned int type, unsigned int flags)
void __EXPORTED nfct_helper_policy_attr_set(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const void *data)
void __EXPORTED nfct_helper_attr_unset(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
const char __EXPORTED * nfct_helper_attr_get_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
uint16_t __EXPORTED nfct_helper_attr_get_u16(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
uint8_t __EXPORTED nfct_helper_attr_get_u8(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void __EXPORTED nfct_helper_attr_set_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type, const char *name)
struct nfct_helper __EXPORTED * nfct_helper_alloc(void)
void __EXPORTED nfct_helper_free(struct nfct_helper *h)
void __EXPORTED nfct_helper_attr_set(struct nfct_helper *h, enum nfct_helper_attr_type type, const void *data)
void __EXPORTED nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *h)
int __EXPORTED nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfct_helper *h)
struct nlmsghdr __EXPORTED * nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd, uint16_t flags, uint32_t seq)