libnetfilter_cthelper  1.0.1
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 
102 struct nfct_helper __EXPORTED *nfct_helper_alloc(void)
103 {
104  return calloc(1, sizeof(struct nfct_helper));
105 }
106 
111 void __EXPORTED nfct_helper_free(struct nfct_helper *h)
112 {
113  int i;
114 
115  for (i=0; i<NF_CT_HELPER_CLASS_MAX; i++) {
116  if (h->expect_policy[i])
117  free(h->expect_policy[i]);
118  }
119  free(h);
120 }
121 
129 {
130  return calloc(1, sizeof(struct nfct_helper_policy));
131 }
132 
137 void __EXPORTED nfct_helper_policy_free(struct nfct_helper_policy *p)
138 {
139  free(p);
140 }
141 
148 void __EXPORTED
150  enum nfct_helper_policy_attr_type type,
151  const void *data)
152 {
153  switch(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);
158  break;
159  case NFCTH_ATTR_POLICY_TIMEOUT:
160  p->expect_timeout = *((uint32_t *) data);
161  p->bitset |= (1 << NFCTH_ATTR_POLICY_TIMEOUT);
162  break;
163  case NFCTH_ATTR_POLICY_MAX:
164  p->expect_max = *((uint32_t *) data);
165  p->bitset |= (1 << NFCTH_ATTR_POLICY_MAX);
166  break;
167  }
168 }
169 
176 void __EXPORTED
178  enum nfct_helper_policy_attr_type type,
179  const char *name)
180 {
181  nfct_helper_policy_attr_set(p, type, name);
182 }
183 
184 void __EXPORTED
185 nfct_helper_policy_attr_set_u32(struct nfct_helper_policy *p,
186  enum nfct_helper_policy_attr_type type,
187  uint32_t value)
188 {
189  nfct_helper_policy_attr_set(p, type, &value);
190 }
191 
198 void __EXPORTED
200  enum nfct_helper_attr_type type, const void *data)
201 {
202  switch(type) {
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);
207  break;
208  case NFCTH_ATTR_QUEUE_NUM:
209  h->queue_num = *((uint32_t *) data);
210  h->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
211  break;
212  case NFCTH_ATTR_PROTO_L3NUM:
213  h->tuple.l3num = *((uint16_t *) data);
214  h->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
215  break;
216  case NFCTH_ATTR_PROTO_L4NUM:
217  h->tuple.l4num = *((uint8_t *) data);
218  h->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
219  break;
220  case NFCTH_ATTR_PRIV_DATA_LEN:
221  h->priv_data_len = *((uint32_t *) data);
222  h->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
223  break;
224  case NFCTH_ATTR_POLICY1:
225  h->expect_policy[0] = (struct nfct_helper_policy *)data;
226  h->bitset |= (1 << NFCTH_ATTR_POLICY1);
227  break;
228  case NFCTH_ATTR_POLICY2:
229  h->expect_policy[1] = (struct nfct_helper_policy *)data;
230  h->bitset |= (1 << NFCTH_ATTR_POLICY2);
231  break;
232  case NFCTH_ATTR_POLICY3:
233  h->expect_policy[2] = (struct nfct_helper_policy *)data;
234  h->bitset |= (1 << NFCTH_ATTR_POLICY3);
235  break;
236  case NFCTH_ATTR_POLICY4:
237  h->expect_policy[3] = (struct nfct_helper_policy *)data;
238  h->bitset |= (1 << NFCTH_ATTR_POLICY4);
239  break;
240  case NFCTH_ATTR_STATUS:
241  h->status = *((uint32_t *) data);
242  h->bitset |= (1 << NFCTH_ATTR_STATUS);
243  break;
244  }
245 }
246 
253 void __EXPORTED
254 nfct_helper_attr_set_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type,
255  const char *name)
256 {
257  nfct_helper_attr_set(nfct_helper, type, name);
258 }
259 
260 void __EXPORTED
261 nfct_helper_attr_set_u8(struct nfct_helper *nfct_helper,
262  enum nfct_helper_attr_type type, uint8_t value)
263 {
264  nfct_helper_attr_set(nfct_helper, type, &value);
265 }
266 
267 void __EXPORTED
268 nfct_helper_attr_set_u16(struct nfct_helper *nfct_helper,
269  enum nfct_helper_attr_type type, uint16_t value)
270 {
271  nfct_helper_attr_set(nfct_helper, type, &value);
272 }
273 
274 void __EXPORTED
275 nfct_helper_attr_set_u32(struct nfct_helper *nfct_helper,
276  enum nfct_helper_attr_type type, uint32_t value)
277 {
278  nfct_helper_attr_set(nfct_helper, type, &value);
279 }
280 
286 void __EXPORTED
287 nfct_helper_attr_unset(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
288 {
289  switch(type) {
290  case NFCTH_ATTR_NAME:
291  nfct_helper->bitset &= ~(1 << NFCTH_ATTR_NAME);
292  break;
293  default:
294  /* XXX */
295  break;
296  }
297 }
298 
307 const void __EXPORTED *
309  enum nfct_helper_attr_type type)
310 {
311  const void *ret = NULL;
312 
313  switch(type) {
314  case NFCTH_ATTR_NAME:
315  ret = helper->name;
316  break;
317  case NFCTH_ATTR_QUEUE_NUM:
318  ret = &helper->queue_num;
319  break;
320  case NFCTH_ATTR_PROTO_L3NUM:
321  ret = &helper->tuple.l3num;
322  break;
323  case NFCTH_ATTR_PROTO_L4NUM:
324  ret = &helper->tuple.l4num;
325  break;
326  case NFCTH_ATTR_PRIV_DATA_LEN:
327  ret = &helper->priv_data_len;
328  break;
329  case NFCTH_ATTR_POLICY1:
330  ret = helper->expect_policy[0];
331  break;
332  case NFCTH_ATTR_POLICY2:
333  ret = helper->expect_policy[1];
334  break;
335  case NFCTH_ATTR_POLICY3:
336  ret = helper->expect_policy[2];
337  break;
338  case NFCTH_ATTR_POLICY4:
339  ret = helper->expect_policy[3];
340  break;
341  case NFCTH_ATTR_STATUS:
342  ret = &helper->status;
343  break;
344  default:
345  ret = NULL;
346  }
347  return ret;
348 }
349 
358 const char __EXPORTED *
360  enum nfct_helper_attr_type type)
361 {
362  return (const char *)nfct_helper_attr_get(nfct_helper, type);
363 }
364 
373 uint8_t __EXPORTED
375  enum nfct_helper_attr_type type)
376 {
377  return *((uint8_t *)nfct_helper_attr_get(nfct_helper, type));
378 }
379 
388 uint16_t __EXPORTED
390  enum nfct_helper_attr_type type)
391 {
392  return *((uint16_t *)nfct_helper_attr_get(nfct_helper, type));
393 }
394 
403 uint32_t __EXPORTED
405  enum nfct_helper_attr_type type)
406 {
407  return *((uint32_t *)nfct_helper_attr_get(nfct_helper, type));
408 }
409 
420 int __EXPORTED
421 nfct_helper_snprintf(char *buf, size_t size,
422  struct nfct_helper *helper,
423  unsigned int type, unsigned int flags)
424 {
425  int ret;
426 
427  ret = snprintf(buf, size, "{\n"
428  "\t.name = %s,\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};",
434  nfct_helper_attr_get_str(helper, NFCTH_ATTR_NAME),
435  nfct_helper_attr_get_u32(helper, NFCTH_ATTR_QUEUE_NUM),
436  nfct_helper_attr_get_u16(helper, NFCTH_ATTR_PROTO_L3NUM),
437  nfct_helper_attr_get_u8(helper, NFCTH_ATTR_PROTO_L4NUM),
438  nfct_helper_attr_get_u32(helper, NFCTH_ATTR_PRIV_DATA_LEN),
439  nfct_helper_attr_get_u32(helper, NFCTH_ATTR_STATUS) ?
440  "enabled" : "disabled");
441 
442  return ret;
443 }
444 
479 struct nlmsghdr __EXPORTED *
480 nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd,
481  uint16_t flags, uint32_t seq)
482 {
483  struct nlmsghdr *nlh;
484  struct nfgenmsg *nfh;
485 
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;
490 
491  nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
492  nfh->nfgen_family = AF_UNSPEC;
493  nfh->version = NFNETLINK_V0;
494  nfh->res_id = 0;
495 
496  return nlh;
497 }
498 
499 static void
500 nfct_helper_nlmsg_build_policy(struct nlmsghdr *nlh, uint16_t type,
501  struct nfct_helper_policy *p)
502 {
503  struct nlattr *nest;
504 
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);
511 }
512 
518 void __EXPORTED
519 nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *h)
520 {
521  struct nlattr *nest;
522 
523 
524  if (h->bitset & (1 << NFCTH_ATTR_NAME))
525  mnl_attr_put_strz(nlh, NFCTH_NAME, h->name);
526 
527  if (h->bitset & (1 << NFCTH_ATTR_QUEUE_NUM))
528  mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(h->queue_num));
529 
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));
533  }
534 
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);
542  }
543 
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;
550 
551  if (h->bitset & (1 << NFCTH_ATTR_POLICY1)) {
552  nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET1,
553  h->expect_policy[0]);
554  policy_set_num++;
555  }
556  if (h->bitset & (1 << NFCTH_ATTR_POLICY2)) {
557  nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET2,
558  h->expect_policy[1]);
559  policy_set_num++;
560  }
561  if (h->bitset & (1 << NFCTH_ATTR_POLICY3)) {
562  nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET3,
563  h->expect_policy[2]);
564  policy_set_num++;
565  }
566  if (h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
567  nfct_helper_nlmsg_build_policy(nlh, NFCTH_POLICY_SET4,
568  h->expect_policy[3]);
569  policy_set_num++;
570  }
571 
572  mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM,
573  htonl(policy_set_num));
574 
575  mnl_attr_nest_end(nlh, nest);
576  }
577 
578  if (h->bitset & (1 << NFCTH_ATTR_STATUS))
579  mnl_attr_put_u32(nlh, NFCTH_STATUS, ntohl(h->status));
580 }
581 
582 static int
583 nfct_helper_nlmsg_parse_tuple_cb(const struct nlattr *attr, void *data)
584 {
585  const struct nlattr **tb = data;
586  int type = mnl_attr_get_type(attr);
587 
588  if (mnl_attr_type_valid(attr, NFCTH_TUPLE_MAX) < 0)
589  return MNL_CB_OK;
590 
591  switch(type) {
592  case NFCTH_TUPLE_L3PROTONUM:
593  if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
594  perror("mnl_attr_validate");
595  return MNL_CB_ERROR;
596  }
597  break;
598  case NFCTH_TUPLE_L4PROTONUM:
599  if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
600  perror("mnl_attr_validate");
601  return MNL_CB_ERROR;
602  }
603  break;
604  default:
605  break;
606  }
607  tb[type] = attr;
608  return MNL_CB_OK;
609 }
610 
611 static void
612 nfct_helper_nlmsg_parse_tuple(const struct nlattr *attr,
613  struct nfct_helper *helper)
614 {
615  struct nlattr *tb[NFCTH_TUPLE_MAX+1] = {};
616 
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])));
621  }
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]));
625  }
626 }
627 
628 static int
629 nfct_helper_nlmsg_parse_policy_cb(const struct nlattr *attr, void *data)
630 {
631  const struct nlattr **tb = data;
632  int type = mnl_attr_get_type(attr);
633 
634  if (mnl_attr_type_valid(attr, NFCTH_POLICY_MAX) < 0)
635  return MNL_CB_OK;
636 
637  switch(type) {
638  case NFCTH_POLICY_NAME:
639  if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
640  perror("mnl_attr_validate");
641  return MNL_CB_ERROR;
642  }
643  break;
644  case NFCTH_POLICY_EXPECT_MAX:
645  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
646  perror("mnl_attr_validate");
647  return MNL_CB_ERROR;
648  }
649  break;
650  case NFCTH_POLICY_EXPECT_TIMEOUT:
651  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
652  perror("mnl_attr_validate");
653  return MNL_CB_ERROR;
654  }
655  break;
656  default:
657  break;
658  }
659  tb[type] = attr;
660  return MNL_CB_OK;
661 }
662 
663 static int
664 nfct_helper_nlmsg_parse_policy_set_cb(const struct nlattr *attr, void *data)
665 {
666  const struct nlattr **tb = data;
667  int type = mnl_attr_get_type(attr);
668 
669  if (mnl_attr_type_valid(attr, NFCTH_POLICY_SET_MAX) < 0)
670  return MNL_CB_OK;
671 
672  switch(type) {
673  case NFCTH_POLICY_SET_NUM:
674  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
675  perror("mnl_attr_validate");
676  return MNL_CB_ERROR;
677  }
678  break;
679  default:
680  /* NFCTH_POLICY_SET1, 2, 3 and 4. */
681  break;
682  }
683  tb[type] = attr;
684  return MNL_CB_OK;
685 }
686 
687 static void
688 nfct_helper_nlmsg_parse_policy(const struct nlattr *attr,
689  struct nfct_helper *helper)
690 {
691  struct nlattr *tb[NFCTH_POLICY_MAX+1] = {};
692  struct nfct_helper_policy *p;
693 
695  if (p == NULL)
696  return;
697 
698  mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_cb, tb);
699  if (tb[NFCTH_POLICY_NAME]) {
700  nfct_helper_policy_attr_set_str(p, NFCTH_ATTR_POLICY_NAME,
701  mnl_attr_get_str(tb[NFCTH_POLICY_NAME]));
702  }
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])));
706  }
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])));
710  }
711 
712  helper->expect_policy[helper->policy_num++] = p;
713 }
714 
715 static void
716 nfct_helper_nlmsg_parse_policy_set(const struct nlattr *attr,
717  struct nfct_helper *helper)
718 {
719  struct nlattr *tb[NFCTH_POLICY_SET_MAX+1] = {};
720  int i, policy_num = 0;
721 
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]));
725 
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],
729  helper);
730  }
731  }
732 }
733 
734 static int
735 nfct_helper_nlmsg_parse_attr_cb(const struct nlattr *attr, void *data)
736 {
737  const struct nlattr **tb = data;
738  int type = mnl_attr_get_type(attr);
739 
740  if (mnl_attr_type_valid(attr, NFCTH_MAX) < 0)
741  return MNL_CB_OK;
742 
743  switch(type) {
744  case NFCTH_NAME:
745  if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
746  perror("mnl_attr_validate");
747  return MNL_CB_ERROR;
748  }
749  break;
750  case NFCTH_QUEUE_NUM:
751  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
752  perror("mnl_attr_validate");
753  return MNL_CB_ERROR;
754  }
755  break;
756  case NFCTH_TUPLE:
757  if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
758  perror("mnl_attr_validate");
759  return MNL_CB_ERROR;
760  }
761  break;
762  case NFCTH_POLICY:
763  if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
764  perror("mnl_attr_validate");
765  return MNL_CB_ERROR;
766  }
767  break;
768  }
769  tb[type] = attr;
770  return MNL_CB_OK;
771 }
772 
781 int __EXPORTED
782 nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh,
783  struct nfct_helper *h)
784 {
785  struct nlattr *tb[NFCTH_MAX+1] = {};
786  struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
787 
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])
791  return -1;
792 
793  if (tb[NFCTH_NAME]) {
794  nfct_helper_attr_set_str(h, NFCTH_ATTR_NAME,
795  mnl_attr_get_str(tb[NFCTH_NAME]));
796  }
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])));
800  }
801  if (tb[NFCTH_TUPLE])
802  nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], h);
803 
804  if (tb[NFCTH_POLICY])
805  nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], h);
806 
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])));
810  }
811 
812  if (tb[NFCTH_STATUS]) {
813  nfct_helper_attr_set_u32(h, NFCTH_ATTR_STATUS,
814  ntohl(mnl_attr_get_u32(tb[NFCTH_STATUS])));
815  }
816  return 0;
817 }
818 
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)
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)
uint16_t __EXPORTED nfct_helper_attr_get_u16(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
struct nfct_helper __EXPORTED * nfct_helper_alloc(void)
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)
const void __EXPORTED * nfct_helper_attr_get(struct nfct_helper *helper, enum nfct_helper_attr_type type)
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)
struct nfct_helper_policy __EXPORTED * nfct_helper_policy_alloc(void)
const char __EXPORTED * nfct_helper_attr_get_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
void __EXPORTED nfct_helper_nlmsg_build_payload(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)
int __EXPORTED nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfct_helper *h)