libnftnl  1.0.5
masq.c
1 /*
2  * (C) 2014 by Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
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 
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <arpa/inet.h>
13 #include <errno.h>
14 #include <inttypes.h>
15 
16 #include <linux/netfilter/nf_tables.h>
17 
18 #include "internal.h"
19 #include <libmnl/libmnl.h>
20 #include <libnftnl/expr.h>
21 #include <libnftnl/rule.h>
22 
24  uint32_t flags;
25 };
26 
27 static int
28 nftnl_expr_masq_set(struct nftnl_expr *e, uint16_t type,
29  const void *data, uint32_t data_len)
30 {
31  struct nftnl_expr_masq *masq = nftnl_expr_data(e);
32 
33  switch (type) {
34  case NFTNL_EXPR_MASQ_FLAGS:
35  masq->flags = *((uint32_t *)data);
36  break;
37  default:
38  return -1;
39  }
40  return 0;
41 }
42 
43 static const void *
44 nftnl_expr_masq_get(const struct nftnl_expr *e, uint16_t type,
45  uint32_t *data_len)
46 {
47  struct nftnl_expr_masq *masq = nftnl_expr_data(e);
48 
49  switch (type) {
50  case NFTNL_EXPR_MASQ_FLAGS:
51  *data_len = sizeof(masq->flags);
52  return &masq->flags;
53  }
54  return NULL;
55 }
56 
57 static int nftnl_expr_masq_cb(const struct nlattr *attr, void *data)
58 {
59  const struct nlattr **tb = data;
60  int type = mnl_attr_get_type(attr);
61 
62  if (mnl_attr_type_valid(attr, NFTA_MASQ_MAX) < 0)
63  return MNL_CB_OK;
64 
65  switch (type) {
66  case NFTA_MASQ_FLAGS:
67  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
68  abi_breakage();
69  break;
70  }
71 
72  tb[type] = attr;
73  return MNL_CB_OK;
74 }
75 
76 static void
77 nftnl_expr_masq_build(struct nlmsghdr *nlh, struct nftnl_expr *e)
78 {
79  struct nftnl_expr_masq *masq = nftnl_expr_data(e);
80 
81  if (e->flags & (1 << NFTNL_EXPR_MASQ_FLAGS))
82  mnl_attr_put_u32(nlh, NFTA_MASQ_FLAGS, htobe32(masq->flags));
83 }
84 
85 static int
86 nftnl_expr_masq_parse(struct nftnl_expr *e, struct nlattr *attr)
87 {
88  struct nftnl_expr_masq *masq = nftnl_expr_data(e);
89  struct nlattr *tb[NFTA_MASQ_MAX+1] = {};
90 
91  if (mnl_attr_parse_nested(attr, nftnl_expr_masq_cb, tb) < 0)
92  return -1;
93 
94  if (tb[NFTA_MASQ_FLAGS]) {
95  masq->flags = be32toh(mnl_attr_get_u32(tb[NFTA_MASQ_FLAGS]));
96  e->flags |= (1 << NFTNL_EXPR_MASQ_FLAGS);
97  }
98 
99  return 0;
100 }
101 
102 static int
103 nftnl_expr_masq_json_parse(struct nftnl_expr *e, json_t *root,
104  struct nftnl_parse_err *err)
105 {
106 #ifdef JSON_PARSING
107  uint32_t flags;
108 
109  if (nftnl_jansson_parse_val(root, "flags", NFTNL_TYPE_U32, &flags,
110  err) == 0)
111  nftnl_expr_set_u32(e, NFTNL_EXPR_MASQ_FLAGS, flags);
112 
113  return 0;
114 #else
115  errno = EOPNOTSUPP;
116  return -1;
117 #endif
118 }
119 
120 static int
121 nftnl_expr_masq_xml_parse(struct nftnl_expr *e, mxml_node_t *tree,
122  struct nftnl_parse_err *err)
123 {
124 #ifdef XML_PARSING
125  uint32_t flags;
126 
127  if (nftnl_mxml_num_parse(tree, "flags", MXML_DESCEND_FIRST, BASE_DEC,
128  &flags, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
129  nftnl_expr_set_u32(e, NFTNL_EXPR_MASQ_FLAGS, flags);
130 
131  return 0;
132 #else
133  errno = EOPNOTSUPP;
134  return -1;
135 #endif
136 }
137 static int nftnl_expr_masq_export(char *buf, size_t size,
138  struct nftnl_expr *e, int type)
139 {
140  struct nftnl_expr_masq *masq = nftnl_expr_data(e);
141  NFTNL_BUF_INIT(b, buf, size);
142 
143  if (e->flags & (1 << NFTNL_EXPR_MASQ_FLAGS))
144  nftnl_buf_u32(&b, type, masq->flags, FLAGS);
145 
146  return nftnl_buf_done(&b);
147 }
148 
149 static int nftnl_expr_masq_snprintf_default(char *buf, size_t len,
150  struct nftnl_expr *e)
151 {
152  struct nftnl_expr_masq *masq = nftnl_expr_data(e);
153 
154  if (e->flags & (1 << NFTNL_EXPR_MASQ_FLAGS))
155  return snprintf(buf, len, "flags 0x%x ", masq->flags);
156 
157  return 0;
158 }
159 
160 static int nftnl_expr_masq_snprintf(char *buf, size_t len, uint32_t type,
161  uint32_t flags, struct nftnl_expr *e)
162 {
163  switch (type) {
164  case NFTNL_OUTPUT_DEFAULT:
165  return nftnl_expr_masq_snprintf_default(buf, len, e);
166  case NFTNL_OUTPUT_XML:
167  case NFTNL_OUTPUT_JSON:
168  return nftnl_expr_masq_export(buf, len, e, type);
169  default:
170  break;
171  }
172  return -1;
173 }
174 
175 struct expr_ops expr_ops_masq = {
176  .name = "masq",
177  .alloc_len = sizeof(struct nftnl_expr_masq),
178  .max_attr = NFTA_MASQ_MAX,
179  .set = nftnl_expr_masq_set,
180  .get = nftnl_expr_masq_get,
181  .parse = nftnl_expr_masq_parse,
182  .build = nftnl_expr_masq_build,
183  .snprintf = nftnl_expr_masq_snprintf,
184  .xml_parse = nftnl_expr_masq_xml_parse,
185  .json_parse = nftnl_expr_masq_json_parse,
186 };