15 #include <arpa/inet.h>
17 #include <linux/netfilter/nf_tables.h>
20 #include <libmnl/libmnl.h>
21 #include <libnftnl/expr.h>
22 #include <libnftnl/rule.h>
33 static int nftnl_expr_log_set(
struct nftnl_expr *e, uint16_t type,
34 const void *data, uint32_t data_len)
39 case NFTNL_EXPR_LOG_PREFIX:
43 log->prefix = strdup(data);
45 case NFTNL_EXPR_LOG_GROUP:
46 log->group = *((uint16_t *)data);
48 case NFTNL_EXPR_LOG_SNAPLEN:
49 log->snaplen = *((uint32_t *)data);
51 case NFTNL_EXPR_LOG_QTHRESHOLD:
52 log->qthreshold = *((uint16_t *)data);
54 case NFTNL_EXPR_LOG_LEVEL:
55 log->level = *((uint32_t *)data);
57 case NFTNL_EXPR_LOG_FLAGS:
58 log->flags = *((uint32_t *)data);
67 nftnl_expr_log_get(
const struct nftnl_expr *e, uint16_t type,
73 case NFTNL_EXPR_LOG_PREFIX:
74 *data_len = strlen(log->prefix)+1;
76 case NFTNL_EXPR_LOG_GROUP:
77 *data_len =
sizeof(log->group);
79 case NFTNL_EXPR_LOG_SNAPLEN:
80 *data_len =
sizeof(log->snaplen);
82 case NFTNL_EXPR_LOG_QTHRESHOLD:
83 *data_len =
sizeof(log->qthreshold);
84 return &log->qthreshold;
85 case NFTNL_EXPR_LOG_LEVEL:
86 *data_len =
sizeof(log->level);
88 case NFTNL_EXPR_LOG_FLAGS:
89 *data_len =
sizeof(log->flags);
95 static int nftnl_expr_log_cb(
const struct nlattr *attr,
void *data)
97 const struct nlattr **tb = data;
98 int type = mnl_attr_get_type(attr);
100 if (mnl_attr_type_valid(attr, NFTA_LOG_MAX) < 0)
104 case NFTA_LOG_PREFIX:
105 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
109 case NFTA_LOG_QTHRESHOLD:
110 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
113 case NFTA_LOG_SNAPLEN:
116 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
126 nftnl_expr_log_build(
struct nlmsghdr *nlh,
struct nftnl_expr *e)
130 if (e->flags & (1 << NFTNL_EXPR_LOG_PREFIX))
131 mnl_attr_put_strz(nlh, NFTA_LOG_PREFIX, log->prefix);
132 if (e->flags & (1 << NFTNL_EXPR_LOG_GROUP))
133 mnl_attr_put_u16(nlh, NFTA_LOG_GROUP, htons(log->group));
134 if (e->flags & (1 << NFTNL_EXPR_LOG_SNAPLEN))
135 mnl_attr_put_u32(nlh, NFTA_LOG_SNAPLEN, htonl(log->snaplen));
136 if (e->flags & (1 << NFTNL_EXPR_LOG_QTHRESHOLD))
137 mnl_attr_put_u16(nlh, NFTA_LOG_QTHRESHOLD, htons(log->qthreshold));
138 if (e->flags & (1 << NFTNL_EXPR_LOG_LEVEL))
139 mnl_attr_put_u32(nlh, NFTA_LOG_LEVEL, htonl(log->level));
140 if (e->flags & (1 << NFTNL_EXPR_LOG_FLAGS))
141 mnl_attr_put_u32(nlh, NFTA_LOG_FLAGS, htonl(log->flags));
145 nftnl_expr_log_parse(
struct nftnl_expr *e,
struct nlattr *attr)
148 struct nlattr *tb[NFTA_LOG_MAX+1] = {};
150 if (mnl_attr_parse_nested(attr, nftnl_expr_log_cb, tb) < 0)
153 if (tb[NFTA_LOG_PREFIX]) {
157 log->prefix = strdup(mnl_attr_get_str(tb[NFTA_LOG_PREFIX]));
158 e->flags |= (1 << NFTNL_EXPR_LOG_PREFIX);
160 if (tb[NFTA_LOG_GROUP]) {
161 log->group = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_GROUP]));
162 e->flags |= (1 << NFTNL_EXPR_LOG_GROUP);
164 if (tb[NFTA_LOG_SNAPLEN]) {
165 log->snaplen = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_SNAPLEN]));
166 e->flags |= (1 << NFTNL_EXPR_LOG_SNAPLEN);
168 if (tb[NFTA_LOG_QTHRESHOLD]) {
169 log->qthreshold = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_QTHRESHOLD]));
170 e->flags |= (1 << NFTNL_EXPR_LOG_QTHRESHOLD);
172 if (tb[NFTA_LOG_LEVEL]) {
173 log->level = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_LEVEL]));
174 e->flags |= (1 << NFTNL_EXPR_LOG_LEVEL);
176 if (tb[NFTA_LOG_FLAGS]) {
177 log->flags = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_FLAGS]));
178 e->flags |= (1 << NFTNL_EXPR_LOG_FLAGS);
184 static int nftnl_expr_log_json_parse(
struct nftnl_expr *e, json_t *root,
185 struct nftnl_parse_err *err)
189 uint32_t snaplen, level, flags;
190 uint16_t group, qthreshold;
192 prefix = nftnl_jansson_parse_str(root,
"prefix", err);
194 nftnl_expr_set_str(e, NFTNL_EXPR_LOG_PREFIX, prefix);
196 if (nftnl_jansson_parse_val(root,
"group", NFTNL_TYPE_U16, &group,
198 nftnl_expr_set_u16(e, NFTNL_EXPR_LOG_GROUP, group);
200 if (nftnl_jansson_parse_val(root,
"snaplen", NFTNL_TYPE_U32, &snaplen,
202 nftnl_expr_set_u32(e, NFTNL_EXPR_LOG_SNAPLEN, snaplen);
204 if (nftnl_jansson_parse_val(root,
"qthreshold", NFTNL_TYPE_U16,
205 &qthreshold, err) == 0)
206 nftnl_expr_set_u16(e, NFTNL_EXPR_LOG_QTHRESHOLD, qthreshold);
208 if (nftnl_jansson_parse_val(root,
"level", NFTNL_TYPE_U32, &level,
210 nftnl_expr_set_u32(e, NFTNL_EXPR_LOG_LEVEL, level);
212 if (nftnl_jansson_parse_val(root,
"flags", NFTNL_TYPE_U32, &flags,
214 nftnl_expr_set_u32(e, NFTNL_EXPR_LOG_FLAGS, flags);
223 static int nftnl_expr_log_xml_parse(
struct nftnl_expr *e,
225 struct nftnl_parse_err *err)
229 uint32_t snaplen, level, flags;
230 uint16_t group, qthreshold;
232 prefix = nftnl_mxml_str_parse(tree,
"prefix", MXML_DESCEND_FIRST,
233 NFTNL_XML_MAND, err);
235 nftnl_expr_set_str(e, NFTNL_EXPR_LOG_PREFIX, prefix);
237 if (nftnl_mxml_num_parse(tree,
"group", MXML_DESCEND_FIRST, BASE_DEC,
238 &group, NFTNL_TYPE_U16, NFTNL_XML_MAND, err) == 0)
239 nftnl_expr_set_u16(e, NFTNL_EXPR_LOG_GROUP, group);
241 if (nftnl_mxml_num_parse(tree,
"snaplen", MXML_DESCEND_FIRST, BASE_DEC,
242 &snaplen, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
243 nftnl_expr_set_u32(e, NFTNL_EXPR_LOG_SNAPLEN, snaplen);
245 if (nftnl_mxml_num_parse(tree,
"qthreshold", MXML_DESCEND_FIRST, BASE_DEC,
246 &qthreshold, NFTNL_TYPE_U16, NFTNL_XML_MAND,
248 nftnl_expr_set_u16(e, NFTNL_EXPR_LOG_QTHRESHOLD, qthreshold);
250 if (nftnl_mxml_num_parse(tree,
"level", MXML_DESCEND_FIRST, BASE_DEC,
251 &level, NFTNL_TYPE_U16, NFTNL_XML_MAND,
253 nftnl_expr_set_u32(e, NFTNL_EXPR_LOG_LEVEL, level);
255 if (nftnl_mxml_num_parse(tree,
"flags", MXML_DESCEND_FIRST, BASE_DEC,
256 &flags, NFTNL_TYPE_U16, NFTNL_XML_MAND,
258 nftnl_expr_set_u32(e, NFTNL_EXPR_LOG_FLAGS, flags);
267 static int nftnl_expr_log_snprintf_default(
char *buf,
size_t size,
268 struct nftnl_expr *e)
271 int ret, offset = 0, len = size;
273 ret = snprintf(buf, len,
"prefix %s ", log->prefix);
274 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
276 if (e->flags & (1 << NFTNL_EXPR_LOG_GROUP)) {
277 ret = snprintf(buf + offset, len,
278 "group %u snaplen %u qthreshold %u",
279 log->group, log->snaplen, log->qthreshold);
280 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
281 }
else if (e->flags & (1 << NFTNL_EXPR_LOG_LEVEL)) {
282 ret = snprintf(buf + offset, len,
"level %u flags %u",
283 log->level, log->flags);
284 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
290 static int nftnl_expr_log_export(
char *buf,
size_t size,
291 struct nftnl_expr *e,
int type)
294 NFTNL_BUF_INIT(b, buf, size);
296 if (e->flags & (1 << NFTNL_EXPR_LOG_PREFIX))
297 nftnl_buf_str(&b, type, log->prefix, PREFIX);
298 if (e->flags & (1 << NFTNL_EXPR_LOG_GROUP))
299 nftnl_buf_u32(&b, type, log->group, GROUP);
300 if (e->flags & (1 << NFTNL_EXPR_LOG_SNAPLEN))
301 nftnl_buf_u32(&b, type, log->snaplen, SNAPLEN);
302 if (e->flags & (1 << NFTNL_EXPR_LOG_QTHRESHOLD))
303 nftnl_buf_u32(&b, type, log->qthreshold, QTHRESH);
304 if (e->flags & (1 << NFTNL_EXPR_LOG_LEVEL))
305 nftnl_buf_u32(&b, type, log->level, LEVEL);
306 if (e->flags & (1 << NFTNL_EXPR_LOG_FLAGS))
307 nftnl_buf_u32(&b, type, log->level, FLAGS);
309 return nftnl_buf_done(&b);
313 nftnl_expr_log_snprintf(
char *buf,
size_t len, uint32_t type,
314 uint32_t flags,
struct nftnl_expr *e)
317 case NFTNL_OUTPUT_DEFAULT:
318 return nftnl_expr_log_snprintf_default(buf, len, e);
319 case NFTNL_OUTPUT_XML:
320 case NFTNL_OUTPUT_JSON:
321 return nftnl_expr_log_export(buf, len, e, type);
328 static void nftnl_expr_log_free(
struct nftnl_expr *e)
335 struct expr_ops expr_ops_log = {
338 .max_attr = NFTA_LOG_MAX,
339 .free = nftnl_expr_log_free,
340 .set = nftnl_expr_log_set,
341 .get = nftnl_expr_log_get,
342 .parse = nftnl_expr_log_parse,
343 .build = nftnl_expr_log_build,
344 .snprintf = nftnl_expr_log_snprintf,
345 .xml_parse = nftnl_expr_log_xml_parse,
346 .json_parse = nftnl_expr_log_json_parse,