16 #include <arpa/inet.h>
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;
116 for (i=0; i<NF_CT_HELPER_CLASS_MAX; i++) {
117 if (h->expect_policy[i])
118 free(h->expect_policy[i]);
154 enum nfct_helper_policy_attr_type type,
158 case NFCTH_ATTR_POLICY_NAME:
159 strncpy(p->name, data, NF_CT_HELPER_NAME_MAX);
160 p->name[NF_CT_HELPER_NAME_MAX-1] =
'\0';
161 p->bitset |= (1 << NFCTH_ATTR_POLICY_NAME);
163 case NFCTH_ATTR_POLICY_TIMEOUT:
164 p->expect_timeout = *((uint32_t *) data);
165 p->bitset |= (1 << NFCTH_ATTR_POLICY_TIMEOUT);
167 case NFCTH_ATTR_POLICY_MAX:
168 p->expect_max = *((uint32_t *) data);
169 p->bitset |= (1 << NFCTH_ATTR_POLICY_MAX);
183 enum nfct_helper_policy_attr_type type,
192 enum nfct_helper_policy_attr_type type,
197 EXPORT_SYMBOL(nfct_helper_policy_attr_set_u32);
207 enum nfct_helper_attr_type type,
const void *data)
210 case NFCTH_ATTR_NAME:
211 strncpy(h->name, data, NF_CT_HELPER_NAME_MAX);
212 h->name[NF_CT_HELPER_NAME_MAX-1] =
'\0';
213 h->bitset |= (1 << NFCTH_ATTR_NAME);
215 case NFCTH_ATTR_QUEUE_NUM:
216 h->queue_num = *((uint32_t *) data);
217 h->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
219 case NFCTH_ATTR_PROTO_L3NUM:
220 h->tuple.l3num = *((uint16_t *) data);
221 h->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
223 case NFCTH_ATTR_PROTO_L4NUM:
224 h->tuple.l4num = *((uint8_t *) data);
225 h->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
227 case NFCTH_ATTR_PRIV_DATA_LEN:
228 h->priv_data_len = *((uint32_t *) data);
229 h->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
231 case NFCTH_ATTR_POLICY1:
233 h->bitset |= (1 << NFCTH_ATTR_POLICY1);
235 case NFCTH_ATTR_POLICY2:
237 h->bitset |= (1 << NFCTH_ATTR_POLICY2);
239 case NFCTH_ATTR_POLICY3:
241 h->bitset |= (1 << NFCTH_ATTR_POLICY3);
243 case NFCTH_ATTR_POLICY4:
245 h->bitset |= (1 << NFCTH_ATTR_POLICY4);
247 case NFCTH_ATTR_STATUS:
248 h->status = *((uint32_t *) data);
249 h->bitset |= (1 << NFCTH_ATTR_STATUS);
271 enum nfct_helper_attr_type type, uint8_t value)
275 EXPORT_SYMBOL(nfct_helper_attr_set_u8);
279 enum nfct_helper_attr_type type, uint16_t value)
283 EXPORT_SYMBOL(nfct_helper_attr_set_u16);
287 enum nfct_helper_attr_type type, uint32_t value)
291 EXPORT_SYMBOL(nfct_helper_attr_set_u32);
302 case NFCTH_ATTR_NAME:
303 nfct_helper->bitset &= ~(1 << NFCTH_ATTR_NAME);
321 enum nfct_helper_attr_type type)
323 const void *ret = NULL;
326 case NFCTH_ATTR_NAME:
329 case NFCTH_ATTR_QUEUE_NUM:
330 ret = &helper->queue_num;
332 case NFCTH_ATTR_PROTO_L3NUM:
333 ret = &helper->tuple.l3num;
335 case NFCTH_ATTR_PROTO_L4NUM:
336 ret = &helper->tuple.l4num;
338 case NFCTH_ATTR_PRIV_DATA_LEN:
339 ret = &helper->priv_data_len;
341 case NFCTH_ATTR_POLICY1:
342 ret = helper->expect_policy[0];
344 case NFCTH_ATTR_POLICY2:
345 ret = helper->expect_policy[1];
347 case NFCTH_ATTR_POLICY3:
348 ret = helper->expect_policy[2];
350 case NFCTH_ATTR_POLICY4:
351 ret = helper->expect_policy[3];
353 case NFCTH_ATTR_STATUS:
354 ret = &helper->status;
373 enum nfct_helper_attr_type type)
388 enum nfct_helper_attr_type type)
403 enum nfct_helper_attr_type type)
418 enum nfct_helper_attr_type type)
436 unsigned int type,
unsigned int flags)
440 ret = snprintf(buf, size,
"{\n"
442 "\t.queuenum = %u,\n"
443 "\t.l3protonum = %u,\n"
444 "\t.l4protonum = %u,\n"
445 "\t.priv_data_len = %u,\n"
446 "\t.status = %s,\n};",
453 "enabled" :
"disabled");
495 uint16_t flags, uint32_t seq)
497 struct nlmsghdr *nlh;
498 struct nfgenmsg *nfh;
500 nlh = mnl_nlmsg_put_header(buf);
501 nlh->nlmsg_type = (NFNL_SUBSYS_CTHELPER << 8) | cmd;
502 nlh->nlmsg_flags = NLM_F_REQUEST | flags;
503 nlh->nlmsg_seq = seq;
505 nfh = mnl_nlmsg_put_extra_header(nlh,
sizeof(
struct nfgenmsg));
506 nfh->nfgen_family = AF_UNSPEC;
507 nfh->version = NFNETLINK_V0;
515 nfct_helper_nlmsg_build_policy(
struct nlmsghdr *nlh,
520 nest = mnl_attr_nest_start(nlh, NFCTH_POLICY_SET);
521 mnl_attr_put_strz(nlh, NFCTH_POLICY_NAME, p->name);
522 mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_MAX, htonl(p->expect_max));
523 mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_TIMEOUT,
524 htonl(p->expect_timeout));
525 mnl_attr_nest_end(nlh, nest);
539 if (h->bitset & (1 << NFCTH_ATTR_NAME))
540 mnl_attr_put_strz(nlh, NFCTH_NAME, h->name);
542 if (h->bitset & (1 << NFCTH_ATTR_QUEUE_NUM))
543 mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(h->queue_num));
545 if (h->bitset & (1 << NFCTH_ATTR_PRIV_DATA_LEN)) {
546 mnl_attr_put_u32(nlh, NFCTH_PRIV_DATA_LEN,
547 htonl(h->priv_data_len));
550 if (h->bitset & (1 << NFCTH_ATTR_PROTO_L3NUM) ||
551 h->bitset & (1 << NFCTH_ATTR_PROTO_L4NUM)) {
552 nest = mnl_attr_nest_start(nlh, NFCTH_TUPLE);
553 mnl_attr_put_u16(nlh, NFCTH_TUPLE_L3PROTONUM,
554 htons(h->tuple.l3num));
555 mnl_attr_put_u8(nlh, NFCTH_TUPLE_L4PROTONUM, h->tuple.l4num);
556 mnl_attr_nest_end(nlh, nest);
559 if (h->bitset & (1 << NFCTH_ATTR_POLICY1) ||
560 h->bitset & (1 << NFCTH_ATTR_POLICY2) ||
561 h->bitset & (1 << NFCTH_ATTR_POLICY3) ||
562 h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
563 nest = mnl_attr_nest_start(nlh, NFCTH_POLICY);
564 int policy_set_num = 0;
566 if (h->bitset & (1 << NFCTH_ATTR_POLICY1)) {
567 nfct_helper_nlmsg_build_policy(nlh,
568 h->expect_policy[0]);
571 if (h->bitset & (1 << NFCTH_ATTR_POLICY2)) {
572 nfct_helper_nlmsg_build_policy(nlh,
573 h->expect_policy[1]);
576 if (h->bitset & (1 << NFCTH_ATTR_POLICY3)) {
577 nfct_helper_nlmsg_build_policy(nlh,
578 h->expect_policy[2]);
581 if (h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
582 nfct_helper_nlmsg_build_policy(nlh,
583 h->expect_policy[3]);
587 mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM,
588 htonl(policy_set_num));
590 mnl_attr_nest_end(nlh, nest);
593 if (h->bitset & (1 << NFCTH_ATTR_STATUS))
594 mnl_attr_put_u32(nlh, NFCTH_STATUS, ntohl(h->status));
599 nfct_helper_nlmsg_parse_tuple_cb(
const struct nlattr *attr,
void *data)
601 const struct nlattr **tb = data;
602 int type = mnl_attr_get_type(attr);
604 if (mnl_attr_type_valid(attr, NFCTH_TUPLE_MAX) < 0)
608 case NFCTH_TUPLE_L3PROTONUM:
609 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
610 perror(
"mnl_attr_validate");
614 case NFCTH_TUPLE_L4PROTONUM:
615 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
616 perror(
"mnl_attr_validate");
628 nfct_helper_nlmsg_parse_tuple(
const struct nlattr *attr,
631 struct nlattr *tb[NFCTH_TUPLE_MAX+1] = {};
633 mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_tuple_cb, tb);
634 if (tb[NFCTH_TUPLE_L3PROTONUM]) {
635 nfct_helper_attr_set_u16(helper, NFCTH_ATTR_PROTO_L3NUM,
636 ntohs(mnl_attr_get_u16(tb[NFCTH_TUPLE_L3PROTONUM])));
638 if (tb[NFCTH_TUPLE_L4PROTONUM]) {
639 nfct_helper_attr_set_u8(helper, NFCTH_ATTR_PROTO_L4NUM,
640 mnl_attr_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]));
645 nfct_helper_nlmsg_parse_policy_cb(
const struct nlattr *attr,
void *data)
647 const struct nlattr **tb = data;
648 int type = mnl_attr_get_type(attr);
650 if (mnl_attr_type_valid(attr, NFCTH_POLICY_MAX) < 0)
654 case NFCTH_POLICY_NAME:
655 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
656 perror(
"mnl_attr_validate");
660 case NFCTH_POLICY_EXPECT_MAX:
661 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
662 perror(
"mnl_attr_validate");
666 case NFCTH_POLICY_EXPECT_TIMEOUT:
667 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
668 perror(
"mnl_attr_validate");
680 nfct_helper_nlmsg_parse_policy_set_cb(
const struct nlattr *attr,
void *data)
682 const struct nlattr **tb = data;
683 int type = mnl_attr_get_type(attr);
685 if (mnl_attr_type_valid(attr, NFCTH_POLICY_SET_MAX) < 0)
689 case NFCTH_POLICY_SET_NUM:
690 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
691 perror(
"mnl_attr_validate");
704 nfct_helper_nlmsg_parse_policy(
const struct nlattr *attr,
707 struct nlattr *tb[NFCTH_POLICY_MAX+1] = {};
714 mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_cb, tb);
715 if (tb[NFCTH_POLICY_NAME]) {
717 mnl_attr_get_str(tb[NFCTH_POLICY_NAME]));
719 if (tb[NFCTH_POLICY_EXPECT_MAX]) {
720 nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_MAX,
721 ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_MAX])));
723 if (tb[NFCTH_POLICY_EXPECT_TIMEOUT]) {
724 nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_TIMEOUT,
725 ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])));
728 helper->expect_policy[helper->policy_num++] = p;
732 nfct_helper_nlmsg_parse_policy_set(
const struct nlattr *attr,
735 struct nlattr *tb[NFCTH_POLICY_SET_MAX+1] = {};
738 mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_set_cb, tb);
739 if (tb[NFCTH_POLICY_SET_NUM]) {
741 ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_SET_NUM]));
743 for (i=0; i<helper->policy_num; i++) {
744 if (tb[NFCTH_POLICY_SET+i]) {
745 nfct_helper_nlmsg_parse_policy(tb[NFCTH_POLICY_SET+i],
752 nfct_helper_nlmsg_parse_attr_cb(
const struct nlattr *attr,
void *data)
754 const struct nlattr **tb = data;
755 int type = mnl_attr_get_type(attr);
757 if (mnl_attr_type_valid(attr, NFCTH_MAX) < 0)
762 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
763 perror(
"mnl_attr_validate");
767 case NFCTH_QUEUE_NUM:
768 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
769 perror(
"mnl_attr_validate");
774 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
775 perror(
"mnl_attr_validate");
780 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
781 perror(
"mnl_attr_validate");
802 struct nlattr *tb[NFCTH_MAX+1] = {};
803 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
805 mnl_attr_parse(nlh,
sizeof(*nfg), nfct_helper_nlmsg_parse_attr_cb, tb);
806 if (!tb[NFCTH_NAME] || !tb[NFCTH_QUEUE_NUM] ||
807 !tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_STATUS])
810 if (tb[NFCTH_NAME]) {
812 mnl_attr_get_str(tb[NFCTH_NAME]));
814 if (tb[NFCTH_ATTR_QUEUE_NUM]) {
815 nfct_helper_attr_set_u32(h, NFCTH_ATTR_QUEUE_NUM,
816 ntohl(mnl_attr_get_u32(tb[NFCTH_QUEUE_NUM])));
819 nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], h);
821 if (tb[NFCTH_POLICY])
822 nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], h);
824 if (tb[NFCTH_PRIV_DATA_LEN]) {
825 nfct_helper_attr_set_u32(h, NFCTH_ATTR_PRIV_DATA_LEN,
826 ntohl(mnl_attr_get_u32(tb[NFCTH_PRIV_DATA_LEN])));
829 if (tb[NFCTH_STATUS]) {
830 nfct_helper_attr_set_u32(h, NFCTH_ATTR_STATUS,
831 ntohl(mnl_attr_get_u32(tb[NFCTH_STATUS])));
int nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfct_helper *h)
void nfct_helper_attr_set_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type, const char *name)
void nfct_helper_policy_attr_set(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const void *data)
struct nfct_helper * nfct_helper_alloc(void)
void nfct_helper_policy_free(struct nfct_helper_policy *p)
struct nfct_helper_policy * nfct_helper_policy_alloc(void)
const void * nfct_helper_attr_get(struct nfct_helper *helper, enum nfct_helper_attr_type type)
uint16_t nfct_helper_attr_get_u16(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *h)
int nfct_helper_snprintf(char *buf, size_t size, struct nfct_helper *helper, unsigned int type, unsigned int flags)
void nfct_helper_policy_attr_set_str(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const char *name)
uint8_t nfct_helper_attr_get_u8(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
struct nlmsghdr * nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd, uint16_t flags, uint32_t seq)
uint32_t nfct_helper_attr_get_u32(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void nfct_helper_attr_set(struct nfct_helper *h, enum nfct_helper_attr_type type, const void *data)
const char * nfct_helper_attr_get_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void nfct_helper_free(struct nfct_helper *h)
void nfct_helper_attr_unset(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)