libnetfilter_cthelper  1.0.0
libnetfilter_cthelper.c
1 /*
2  * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
10  */
11 #include "internal.h"
12 
13 #include <time.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <arpa/inet.h> /* for htonl */
17 
18 #include <libmnl/libmnl.h>
19 #include <linux/netfilter/nfnetlink.h>
20 #include <linux/netfilter/nfnetlink_cthelper.h>
21 
22 #include <libnetfilter_cthelper/libnetfilter_cthelper.h>
23 
59 /* XXX */
60 #ifndef NF_CT_HELPER_NAME_MAX
61 #define NF_CT_HELPER_NAME_MAX 16
62 #endif
63 
64 #ifndef NF_CT_HELPER_CLASS_MAX
65 #define NF_CT_HELPER_CLASS_MAX 4
66 #endif
67 
69  char name[NF_CT_HELPER_NAME_MAX];
70  uint32_t expect_timeout;
71  uint32_t expect_max;
72  uint32_t bitset;
73 };
74 
75 struct nfct_helper {
76  char name[NF_CT_HELPER_NAME_MAX];
77  uint32_t priv_data_len;
78  uint32_t queue_num;
79  uint32_t status;
80  struct {
81  uint16_t l3num;
82  uint8_t l4num;
83  uint16_t port;
84  } tuple;
85  struct nfct_helper_policy *expect_policy[NF_CT_HELPER_CLASS_MAX];
86  uint32_t policy_num;
87 
88  uint32_t bitset;
89 };
90 
103 {
104  return calloc(1, sizeof(struct nfct_helper));
105 }
106 EXPORT_SYMBOL(nfct_helper_alloc);
107 
113 {
114  int i;
115 
116  for (i=0; i<NF_CT_HELPER_CLASS_MAX; i++) {
117  if (h->expect_policy[i])
118  free(h->expect_policy[i]);
119  }
120  free(h);
121 }
122 EXPORT_SYMBOL(nfct_helper_free);
123 
131 {
132  return calloc(1, sizeof(struct nfct_helper_policy));
133 }
134 EXPORT_SYMBOL(nfct_helper_policy_alloc);
135 
141 {
142  free(p);
143 }
144 EXPORT_SYMBOL(nfct_helper_policy_free);
145 
152 void
154  enum nfct_helper_policy_attr_type type,
155  const void *data)
156 {
157  switch(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);
162  break;
163  case NFCTH_ATTR_POLICY_TIMEOUT:
164  p->expect_timeout = *((uint32_t *) data);
165  p->bitset |= (1 << NFCTH_ATTR_POLICY_TIMEOUT);
166  break;
167  case NFCTH_ATTR_POLICY_MAX:
168  p->expect_max = *((uint32_t *) data);
169  p->bitset |= (1 << NFCTH_ATTR_POLICY_MAX);
170  break;
171  }
172 }
173 EXPORT_SYMBOL(nfct_helper_policy_attr_set);
174 
181 void
183  enum nfct_helper_policy_attr_type type,
184  const char *name)
185 {
186  nfct_helper_policy_attr_set(p, type, name);
187 }
188 EXPORT_SYMBOL(nfct_helper_policy_attr_set_str);
189 
190 void
191 nfct_helper_policy_attr_set_u32(struct nfct_helper_policy *p,
192  enum nfct_helper_policy_attr_type type,
193  uint32_t value)
194 {
195  nfct_helper_policy_attr_set(p, type, &value);
196 }
197 EXPORT_SYMBOL(nfct_helper_policy_attr_set_u32);
198 
205 void
207  enum nfct_helper_attr_type type, const void *data)
208 {
209  switch(type) {
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);
214  break;
215  case NFCTH_ATTR_QUEUE_NUM:
216  h->queue_num = *((uint32_t *) data);
217  h->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
218  break;
219  case NFCTH_ATTR_PROTO_L3NUM:
220  h->tuple.l3num = *((uint16_t *) data);
221  h->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
222  break;
223  case NFCTH_ATTR_PROTO_L4NUM:
224  h->tuple.l4num = *((uint8_t *) data);
225  h->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
226  break;
227  case NFCTH_ATTR_PRIV_DATA_LEN:
228  h->priv_data_len = *((uint32_t *) data);
229  h->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
230  break;
231  case NFCTH_ATTR_POLICY1:
232  h->expect_policy[0] = (struct nfct_helper_policy *)data;
233  h->bitset |= (1 << NFCTH_ATTR_POLICY1);
234  break;
235  case NFCTH_ATTR_POLICY2:
236  h->expect_policy[1] = (struct nfct_helper_policy *)data;
237  h->bitset |= (1 << NFCTH_ATTR_POLICY2);
238  break;
239  case NFCTH_ATTR_POLICY3:
240  h->expect_policy[2] = (struct nfct_helper_policy *)data;
241  h->bitset |= (1 << NFCTH_ATTR_POLICY3);
242  break;
243  case NFCTH_ATTR_POLICY4:
244  h->expect_policy[3] = (struct nfct_helper_policy *)data;
245  h->bitset |= (1 << NFCTH_ATTR_POLICY4);
246  break;
247  case NFCTH_ATTR_STATUS:
248  h->status = *((uint32_t *) data);
249  h->bitset |= (1 << NFCTH_ATTR_STATUS);
250  break;
251  }
252 }
253 EXPORT_SYMBOL(nfct_helper_attr_set);
254 
261 void
262 nfct_helper_attr_set_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type,
263  const char *name)
264 {
265  nfct_helper_attr_set(nfct_helper, type, name);
266 }
267 EXPORT_SYMBOL(nfct_helper_attr_set_str);
268 
269 void
270 nfct_helper_attr_set_u8(struct nfct_helper *nfct_helper,
271  enum nfct_helper_attr_type type, uint8_t value)
272 {
273  nfct_helper_attr_set(nfct_helper, type, &value);
274 }
275 EXPORT_SYMBOL(nfct_helper_attr_set_u8);
276 
277 void
278 nfct_helper_attr_set_u16(struct nfct_helper *nfct_helper,
279  enum nfct_helper_attr_type type, uint16_t value)
280 {
281  nfct_helper_attr_set(nfct_helper, type, &value);
282 }
283 EXPORT_SYMBOL(nfct_helper_attr_set_u16);
284 
285 void
286 nfct_helper_attr_set_u32(struct nfct_helper *nfct_helper,
287  enum nfct_helper_attr_type type, uint32_t value)
288 {
289  nfct_helper_attr_set(nfct_helper, type, &value);
290 }
291 EXPORT_SYMBOL(nfct_helper_attr_set_u32);
292 
298 void
299 nfct_helper_attr_unset(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
300 {
301  switch(type) {
302  case NFCTH_ATTR_NAME:
303  nfct_helper->bitset &= ~(1 << NFCTH_ATTR_NAME);
304  break;
305  default:
306  /* XXX */
307  break;
308  }
309 }
310 EXPORT_SYMBOL(nfct_helper_attr_unset);
311 
320 const void *nfct_helper_attr_get(struct nfct_helper *helper,
321  enum nfct_helper_attr_type type)
322 {
323  const void *ret = NULL;
324 
325  switch(type) {
326  case NFCTH_ATTR_NAME:
327  ret = helper->name;
328  break;
329  case NFCTH_ATTR_QUEUE_NUM:
330  ret = &helper->queue_num;
331  break;
332  case NFCTH_ATTR_PROTO_L3NUM:
333  ret = &helper->tuple.l3num;
334  break;
335  case NFCTH_ATTR_PROTO_L4NUM:
336  ret = &helper->tuple.l4num;
337  break;
338  case NFCTH_ATTR_PRIV_DATA_LEN:
339  ret = &helper->priv_data_len;
340  break;
341  case NFCTH_ATTR_POLICY1:
342  ret = helper->expect_policy[0];
343  break;
344  case NFCTH_ATTR_POLICY2:
345  ret = helper->expect_policy[1];
346  break;
347  case NFCTH_ATTR_POLICY3:
348  ret = helper->expect_policy[2];
349  break;
350  case NFCTH_ATTR_POLICY4:
351  ret = helper->expect_policy[3];
352  break;
353  case NFCTH_ATTR_STATUS:
354  ret = &helper->status;
355  break;
356  default:
357  ret = NULL;
358  }
359  return ret;
360 }
361 EXPORT_SYMBOL(nfct_helper_attr_get);
362 
371 const char *
373  enum nfct_helper_attr_type type)
374 {
375  return (const char *)nfct_helper_attr_get(nfct_helper, type);
376 }
377 EXPORT_SYMBOL(nfct_helper_attr_get_str);
378 
388  enum nfct_helper_attr_type type)
389 {
390  return *((uint8_t *)nfct_helper_attr_get(nfct_helper, type));
391 }
392 EXPORT_SYMBOL(nfct_helper_attr_get_u8);
393 
403  enum nfct_helper_attr_type type)
404 {
405  return *((uint16_t *)nfct_helper_attr_get(nfct_helper, type));
406 }
407 EXPORT_SYMBOL(nfct_helper_attr_get_u16);
408 
418  enum nfct_helper_attr_type type)
419 {
420  return *((uint32_t *)nfct_helper_attr_get(nfct_helper, type));
421 }
422 EXPORT_SYMBOL(nfct_helper_attr_get_u32);
423 
434 int nfct_helper_snprintf(char *buf, size_t size,
435  struct nfct_helper *helper,
436  unsigned int type, unsigned int flags)
437 {
438  int ret;
439 
440  ret = snprintf(buf, size, "{\n"
441  "\t.name = %s,\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};",
447  nfct_helper_attr_get_str(helper, NFCTH_ATTR_NAME),
448  nfct_helper_attr_get_u32(helper, NFCTH_ATTR_QUEUE_NUM),
449  nfct_helper_attr_get_u16(helper, NFCTH_ATTR_PROTO_L3NUM),
450  nfct_helper_attr_get_u8(helper, NFCTH_ATTR_PROTO_L4NUM),
451  nfct_helper_attr_get_u32(helper, NFCTH_ATTR_PRIV_DATA_LEN),
452  nfct_helper_attr_get_u32(helper, NFCTH_ATTR_STATUS) ?
453  "enabled" : "disabled");
454 
455  return ret;
456 }
457 EXPORT_SYMBOL(nfct_helper_snprintf);
458 
493 struct nlmsghdr *
494 nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd,
495  uint16_t flags, uint32_t seq)
496 {
497  struct nlmsghdr *nlh;
498  struct nfgenmsg *nfh;
499 
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;
504 
505  nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
506  nfh->nfgen_family = AF_UNSPEC;
507  nfh->version = NFNETLINK_V0;
508  nfh->res_id = 0;
509 
510  return nlh;
511 }
512 EXPORT_SYMBOL(nfct_helper_nlmsg_build_hdr);
513 
514 static void
515 nfct_helper_nlmsg_build_policy(struct nlmsghdr *nlh,
516  struct nfct_helper_policy *p)
517 {
518  struct nlattr *nest;
519 
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);
526 }
527 
533 void
534 nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *h)
535 {
536  struct nlattr *nest;
537 
538 
539  if (h->bitset & (1 << NFCTH_ATTR_NAME))
540  mnl_attr_put_strz(nlh, NFCTH_NAME, h->name);
541 
542  if (h->bitset & (1 << NFCTH_ATTR_QUEUE_NUM))
543  mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(h->queue_num));
544 
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));
548  }
549 
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);
557  }
558 
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;
565 
566  if (h->bitset & (1 << NFCTH_ATTR_POLICY1)) {
567  nfct_helper_nlmsg_build_policy(nlh,
568  h->expect_policy[0]);
569  policy_set_num++;
570  }
571  if (h->bitset & (1 << NFCTH_ATTR_POLICY2)) {
572  nfct_helper_nlmsg_build_policy(nlh,
573  h->expect_policy[1]);
574  policy_set_num++;
575  }
576  if (h->bitset & (1 << NFCTH_ATTR_POLICY3)) {
577  nfct_helper_nlmsg_build_policy(nlh,
578  h->expect_policy[2]);
579  policy_set_num++;
580  }
581  if (h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
582  nfct_helper_nlmsg_build_policy(nlh,
583  h->expect_policy[3]);
584  policy_set_num++;
585  }
586 
587  mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM,
588  htonl(policy_set_num));
589 
590  mnl_attr_nest_end(nlh, nest);
591  }
592 
593  if (h->bitset & (1 << NFCTH_ATTR_STATUS))
594  mnl_attr_put_u32(nlh, NFCTH_STATUS, ntohl(h->status));
595 }
596 EXPORT_SYMBOL(nfct_helper_nlmsg_build_payload);
597 
598 static int
599 nfct_helper_nlmsg_parse_tuple_cb(const struct nlattr *attr, void *data)
600 {
601  const struct nlattr **tb = data;
602  int type = mnl_attr_get_type(attr);
603 
604  if (mnl_attr_type_valid(attr, NFCTH_TUPLE_MAX) < 0)
605  return MNL_CB_OK;
606 
607  switch(type) {
608  case NFCTH_TUPLE_L3PROTONUM:
609  if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
610  perror("mnl_attr_validate");
611  return MNL_CB_ERROR;
612  }
613  break;
614  case NFCTH_TUPLE_L4PROTONUM:
615  if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
616  perror("mnl_attr_validate");
617  return MNL_CB_ERROR;
618  }
619  break;
620  default:
621  break;
622  }
623  tb[type] = attr;
624  return MNL_CB_OK;
625 }
626 
627 static void
628 nfct_helper_nlmsg_parse_tuple(const struct nlattr *attr,
629  struct nfct_helper *helper)
630 {
631  struct nlattr *tb[NFCTH_TUPLE_MAX+1] = {};
632 
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])));
637  }
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]));
641  }
642 }
643 
644 static int
645 nfct_helper_nlmsg_parse_policy_cb(const struct nlattr *attr, void *data)
646 {
647  const struct nlattr **tb = data;
648  int type = mnl_attr_get_type(attr);
649 
650  if (mnl_attr_type_valid(attr, NFCTH_POLICY_MAX) < 0)
651  return MNL_CB_OK;
652 
653  switch(type) {
654  case NFCTH_POLICY_NAME:
655  if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
656  perror("mnl_attr_validate");
657  return MNL_CB_ERROR;
658  }
659  break;
660  case NFCTH_POLICY_EXPECT_MAX:
661  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
662  perror("mnl_attr_validate");
663  return MNL_CB_ERROR;
664  }
665  break;
666  case NFCTH_POLICY_EXPECT_TIMEOUT:
667  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
668  perror("mnl_attr_validate");
669  return MNL_CB_ERROR;
670  }
671  break;
672  default:
673  break;
674  }
675  tb[type] = attr;
676  return MNL_CB_OK;
677 }
678 
679 static int
680 nfct_helper_nlmsg_parse_policy_set_cb(const struct nlattr *attr, void *data)
681 {
682  const struct nlattr **tb = data;
683  int type = mnl_attr_get_type(attr);
684 
685  if (mnl_attr_type_valid(attr, NFCTH_POLICY_SET_MAX) < 0)
686  return MNL_CB_OK;
687 
688  switch(type) {
689  case NFCTH_POLICY_SET_NUM:
690  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
691  perror("mnl_attr_validate");
692  return MNL_CB_ERROR;
693  }
694  break;
695  default:
696  /* NFCTH_POLICY_SET1, 2, 3 and 4. */
697  break;
698  }
699  tb[type] = attr;
700  return MNL_CB_OK;
701 }
702 
703 static void
704 nfct_helper_nlmsg_parse_policy(const struct nlattr *attr,
705  struct nfct_helper *helper)
706 {
707  struct nlattr *tb[NFCTH_POLICY_MAX+1] = {};
708  struct nfct_helper_policy *p;
709 
711  if (p == NULL)
712  return;
713 
714  mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_cb, tb);
715  if (tb[NFCTH_POLICY_NAME]) {
716  nfct_helper_policy_attr_set_str(p, NFCTH_ATTR_POLICY_NAME,
717  mnl_attr_get_str(tb[NFCTH_POLICY_NAME]));
718  }
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])));
722  }
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])));
726  }
727 
728  helper->expect_policy[helper->policy_num++] = p;
729 }
730 
731 static void
732 nfct_helper_nlmsg_parse_policy_set(const struct nlattr *attr,
733  struct nfct_helper *helper)
734 {
735  struct nlattr *tb[NFCTH_POLICY_SET_MAX+1] = {};
736  int i;
737 
738  mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_set_cb, tb);
739  if (tb[NFCTH_POLICY_SET_NUM]) {
740  helper->policy_num =
741  ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_SET_NUM]));
742  }
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],
746  helper);
747  }
748  }
749 }
750 
751 static int
752 nfct_helper_nlmsg_parse_attr_cb(const struct nlattr *attr, void *data)
753 {
754  const struct nlattr **tb = data;
755  int type = mnl_attr_get_type(attr);
756 
757  if (mnl_attr_type_valid(attr, NFCTH_MAX) < 0)
758  return MNL_CB_OK;
759 
760  switch(type) {
761  case NFCTH_NAME:
762  if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
763  perror("mnl_attr_validate");
764  return MNL_CB_ERROR;
765  }
766  break;
767  case NFCTH_QUEUE_NUM:
768  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
769  perror("mnl_attr_validate");
770  return MNL_CB_ERROR;
771  }
772  break;
773  case NFCTH_TUPLE:
774  if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
775  perror("mnl_attr_validate");
776  return MNL_CB_ERROR;
777  }
778  break;
779  case NFCTH_POLICY:
780  if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
781  perror("mnl_attr_validate");
782  return MNL_CB_ERROR;
783  }
784  break;
785  }
786  tb[type] = attr;
787  return MNL_CB_OK;
788 }
789 
798 int
799 nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh,
800  struct nfct_helper *h)
801 {
802  struct nlattr *tb[NFCTH_MAX+1] = {};
803  struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
804 
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])
808  return -1;
809 
810  if (tb[NFCTH_NAME]) {
811  nfct_helper_attr_set_str(h, NFCTH_ATTR_NAME,
812  mnl_attr_get_str(tb[NFCTH_NAME]));
813  }
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])));
817  }
818  if (tb[NFCTH_TUPLE])
819  nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], h);
820 
821  if (tb[NFCTH_POLICY])
822  nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], h);
823 
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])));
827  }
828 
829  if (tb[NFCTH_STATUS]) {
830  nfct_helper_attr_set_u32(h, NFCTH_ATTR_STATUS,
831  ntohl(mnl_attr_get_u32(tb[NFCTH_STATUS])));
832  }
833  return 0;
834 }
835 EXPORT_SYMBOL(nfct_helper_nlmsg_parse_payload);
836 
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)