libnetfilter_conntrack  1.0.8
expect/parse_mnl.c
1 /*
2  * (C) 2005-2012 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by
6  * 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 
12 #include "internal/internal.h"
13 #include <libmnl/libmnl.h>
14 
15 static int nlmsg_parse_expection_attr_cb(const struct nlattr *attr, void *data)
16 {
17  const struct nlattr **tb = data;
18  int type = mnl_attr_get_type(attr);
19 
20  /* skip unsupported attribute in user-space */
21  if (mnl_attr_type_valid(attr, CTA_EXPECT_MAX) < 0)
22  return MNL_CB_OK;
23 
24  switch(type) {
25  case CTA_EXPECT_MASTER:
26  case CTA_EXPECT_TUPLE:
27  case CTA_EXPECT_MASK:
28  if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
29  abi_breakage();
30  break;
31  case CTA_EXPECT_TIMEOUT:
32  case CTA_EXPECT_FLAGS:
33  case CTA_EXPECT_ID:
34  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
35  abi_breakage();
36  break;
37  case CTA_EXPECT_HELP_NAME:
38  if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
39  abi_breakage();
40  break;
41  case CTA_EXPECT_ZONE:
42  if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
43  abi_breakage();
44  break;
45  }
46  tb[type] = attr;
47  return MNL_CB_OK;
48 }
49 
50 static int nfexp_nlmsg_parse_nat_attr_cb(const struct nlattr *attr, void *data)
51 {
52  int type = mnl_attr_get_type(attr);
53  const struct nlattr **tb = data;
54 
55  if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
56  return MNL_CB_OK;
57 
58  switch(type) {
59  case CTA_EXPECT_NAT_TUPLE:
60  if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
61  abi_breakage();
62  break;
63  case CTA_EXPECT_NAT_DIR:
64  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
65  abi_breakage();
66  break;
67  }
68 
69  tb[type] = attr;
70  return MNL_CB_OK;
71 }
72 
73 static void nfexp_nlmsg_parse_nat(struct nfgenmsg *nfg,
74  const struct nlattr *attr,
75  struct nf_expect *exp)
76 {
77  struct nlattr *tb[CTA_EXPECT_NAT_MAX + 1] = {};
78 
79  if (mnl_attr_parse_nested(attr, nfexp_nlmsg_parse_nat_attr_cb, tb) < 0)
80  return;
81 
82  exp->nat.orig.l3protonum = nfg->nfgen_family;
83  set_bit(ATTR_ORIG_L3PROTO, exp->nat.set);
84 
85  if (tb[CTA_EXPECT_NAT_TUPLE]) {
86  nfct_parse_tuple(tb[CTA_EXPECT_NAT_TUPLE], &exp->nat.orig,
87  __DIR_ORIG, exp->nat.set);
88  set_bit(ATTR_EXP_NAT_TUPLE, exp->set);
89  }
90  if (tb[CTA_EXPECT_NAT_DIR]) {
91  exp->nat_dir =
92  ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_NAT_DIR]));
93  set_bit(ATTR_EXP_NAT_DIR, exp->set);
94  }
95 }
96 
97 int nfexp_nlmsg_parse(const struct nlmsghdr *nlh, struct nf_expect *exp)
98 {
99  struct nlattr *tb[CTA_EXPECT_MAX+1] = {};
100  struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
101 
102  mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
103  nlmsg_parse_expection_attr_cb, tb);
104 
105  if (tb[CTA_EXPECT_MASTER]) {
106  exp->expected.orig.l3protonum = nfg->nfgen_family;
107  set_bit(ATTR_ORIG_L3PROTO, exp->expected.set);
108 
109  nfct_parse_tuple(tb[CTA_EXPECT_MASTER], &exp->master.orig,
110  __DIR_ORIG, exp->master.set);
111  set_bit(ATTR_EXP_MASTER, exp->set);
112  }
113  if (tb[CTA_EXPECT_TUPLE]) {
114  exp->mask.orig.l3protonum = nfg->nfgen_family;
115  set_bit(ATTR_ORIG_L3PROTO, exp->mask.set);
116 
117  nfct_parse_tuple(tb[CTA_EXPECT_TUPLE], &exp->expected.orig,
118  __DIR_ORIG, exp->expected.set);
119  set_bit(ATTR_EXP_EXPECTED, exp->set);
120  }
121  if (tb[CTA_EXPECT_MASK]) {
122  exp->master.orig.l3protonum = nfg->nfgen_family;
123  set_bit(ATTR_ORIG_L3PROTO, exp->master.set);
124 
125  nfct_parse_tuple(tb[CTA_EXPECT_MASK], &exp->mask.orig,
126  __DIR_ORIG, exp->mask.set);
127  set_bit(ATTR_EXP_MASK, exp->set);
128  }
129  if (tb[CTA_EXPECT_TIMEOUT]) {
130  exp->timeout = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_TIMEOUT]));
131  set_bit(ATTR_EXP_TIMEOUT, exp->set);
132  }
133  if (tb[CTA_EXPECT_ZONE]) {
134  exp->zone = ntohs(mnl_attr_get_u16(tb[CTA_EXPECT_ZONE]));
135  set_bit(ATTR_EXP_ZONE, exp->set);
136  }
137  if (tb[CTA_EXPECT_FLAGS]) {
138  exp->flags = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_FLAGS]));
139  set_bit(ATTR_EXP_FLAGS, exp->set);
140  }
141  if (tb[CTA_EXPECT_HELP_NAME]) {
142  strncpy(exp->helper_name,
143  mnl_attr_get_str(tb[CTA_EXPECT_HELP_NAME]),
144  NFCT_HELPER_NAME_MAX);
145  exp->helper_name[NFCT_HELPER_NAME_MAX - 1] = '\0';
146  set_bit(ATTR_EXP_HELPER_NAME, exp->set);
147  }
148  if (tb[CTA_EXPECT_CLASS]) {
149  exp->class = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_CLASS]));
150  set_bit(ATTR_EXP_CLASS, exp->set);
151  }
152  if (tb[CTA_EXPECT_NAT])
153  nfexp_nlmsg_parse_nat(nfg, tb[CTA_EXPECT_NAT], exp);
154 
155  if (tb[CTA_EXPECT_FN]) {
156  strncpy(exp->expectfn, mnl_attr_get_payload(tb[CTA_EXPECT_FN]),
157  __NFCT_EXPECTFN_MAX);
158  exp->expectfn[__NFCT_EXPECTFN_MAX - 1] = '\0';
159  set_bit(ATTR_EXP_FN, exp->set);
160  }
161 
162  return 0;
163 }