From 5c3bc232dc9d1dd01d589fab096f67d944621fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Falgueras=20Garc=C3=ADa?= Date: Tue, 22 Mar 2016 20:46:24 +0100 Subject: udata: add TLV user data infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These functions allow to create a buffer (struct nftnl_udata_buf) of user data attributes in TLV format (struct nftnl_udata). It is inspired by libmnl/src/attr.c. It can be used to store several TLVs sequentially into an object. Example: struct nftnl_udata_buf *buf; struct nftnl_udata *attr; const char *str = "Hello World!"; buf = nftnl_udata_buf_alloc(UDATA_SIZE); if (!buf) { perror("OOM"); exit(EXIT_FAILURE); } if (!nftnl_udata_put_strz(buf, MY_TYPE, str)) { perror("Can't put attribute \"%s\"", str); exit(EXIT_FAILURE); } nftnl_udata_for_each(buf, attr) printf("%s\n", (char *)nftnl_udata_attr_value(attr)); nftnl_udata_buf_free(buf); Signed-off-by: Carlos Falgueras García Signed-off-by: Pablo Neira Ayuso --- src/Makefile.am | 1 + src/libnftnl.map | 15 +++++++ src/udata.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 src/udata.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index a27e292..7e580e4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,7 @@ libnftnl_la_SOURCES = utils.c \ ruleset.c \ mxml.c \ jansson.c \ + udata.c \ expr.c \ expr_ops.c \ expr/bitwise.c \ diff --git a/src/libnftnl.map b/src/libnftnl.map index 2e193b7..c38e081 100644 --- a/src/libnftnl.map +++ b/src/libnftnl.map @@ -512,4 +512,19 @@ LIBNFTNL_4.1 { nftnl_trace_get_data; nftnl_trace_nlmsg_parse; + + nftnl_udata_buf_alloc; + nftnl_udata_buf_free; + nftnl_udata_buf_len; + nftnl_udata_buf_data; + nftnl_udata_buf_put; + nftnl_udata_start; + nftnl_udata_end; + nftnl_udata_put; + nftnl_udata_put_strz; + nftnl_udata_type; + nftnl_udata_len; + nftnl_udata_get; + nftnl_udata_next; + nftnl_udata_parse; } LIBNFTNL_4; diff --git a/src/udata.c b/src/udata.c new file mode 100644 index 0000000..03aac63 --- /dev/null +++ b/src/udata.c @@ -0,0 +1,135 @@ +/* + * (C) 2012-2016 by Pablo Neira Ayuso + * (C) 2016 by Carlos Falgueras García + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include + +#include +#include +#include + +struct nftnl_udata_buf *nftnl_udata_buf_alloc(uint32_t data_size) +{ + struct nftnl_udata_buf *buf; + + buf = malloc(sizeof(struct nftnl_udata_buf) + data_size); + if (!buf) + return NULL; + buf->size = data_size; + buf->end = buf->data; + + return buf; +} +EXPORT_SYMBOL(nftnl_udata_buf_alloc); + +void nftnl_udata_buf_free(struct nftnl_udata_buf *buf) +{ + free(buf); +} +EXPORT_SYMBOL(nftnl_udata_buf_free); + +uint32_t nftnl_udata_buf_len(const struct nftnl_udata_buf *buf) +{ + return (uint32_t)(buf->end - buf->data); +} +EXPORT_SYMBOL(nftnl_udata_buf_len); + +void *nftnl_udata_buf_data(const struct nftnl_udata_buf *buf) +{ + return (void *)buf->data; +} +EXPORT_SYMBOL(nftnl_udata_buf_data); + +void nftnl_udata_buf_put(struct nftnl_udata_buf *buf, const void *data, + uint32_t len) +{ + memcpy(buf->data, data, len <= buf->size ? len : buf->size); + buf->end = buf->data + len; +} +EXPORT_SYMBOL(nftnl_udata_buf_put); + +struct nftnl_udata *nftnl_udata_start(const struct nftnl_udata_buf *buf) +{ + return (struct nftnl_udata *)buf->data; +} +EXPORT_SYMBOL(nftnl_udata_start); + +struct nftnl_udata *nftnl_udata_end(const struct nftnl_udata_buf *buf) +{ + return (struct nftnl_udata *)buf->end; +} +EXPORT_SYMBOL(nftnl_udata_end); + +bool nftnl_udata_put(struct nftnl_udata_buf *buf, uint8_t type, uint32_t len, + const void *value) +{ + struct nftnl_udata *attr; + + if (buf->size < len + sizeof(struct nftnl_udata)) + return false; + + attr = (struct nftnl_udata *)buf->end; + attr->len = len; + attr->type = type; + memcpy(attr->value, value, len); + + buf->end = (char *)nftnl_udata_next(attr); + + return true; +} +EXPORT_SYMBOL(nftnl_udata_put); + +bool nftnl_udata_put_strz(struct nftnl_udata_buf *buf, uint8_t type, + const char *strz) +{ + return nftnl_udata_put(buf, type, strlen(strz) + 1, strz); +} +EXPORT_SYMBOL(nftnl_udata_put_strz); + +uint8_t nftnl_udata_type(const struct nftnl_udata *attr) +{ + return attr->type; +} +EXPORT_SYMBOL(nftnl_udata_type); + +uint8_t nftnl_udata_len(const struct nftnl_udata *attr) +{ + return attr->len; +} +EXPORT_SYMBOL(nftnl_udata_len); + +void *nftnl_udata_get(const struct nftnl_udata *attr) +{ + return (void *)attr->value; +} +EXPORT_SYMBOL(nftnl_udata_get); + +struct nftnl_udata *nftnl_udata_next(const struct nftnl_udata *attr) +{ + return (struct nftnl_udata *)&attr->value[attr->len]; +} +EXPORT_SYMBOL(nftnl_udata_next); + +int nftnl_udata_parse(const void *data, uint32_t data_len, nftnl_udata_cb_t cb, + void *cb_data) +{ + int ret = 0; + const struct nftnl_udata *attr; + + nftnl_udata_for_each_data(data, data_len, attr) { + ret = cb(attr, cb_data); + if (ret < 0) + return ret; + } + + return ret; +} +EXPORT_SYMBOL(nftnl_udata_parse); -- cgit v1.2.3