summaryrefslogtreecommitdiffstats
path: root/src/utils.c
diff options
context:
space:
mode:
authorArturo Borrero <arturo.borrero.glez@gmail.com>2013-07-25 18:46:35 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-07-25 20:03:21 +0200
commite13819c5f5b6138c4c7e01156d0fd9f58b11702d (patch)
treec4bbc0256f537099a8233915597419843359793b /src/utils.c
parent3ebc57b84c227fcfc55545af85e246ab4cad2041 (diff)
src: xml: consolidate common XML code via nft_mxml_num_parse
This patch moves common XML parsing code to nft_mxml_num_parse(). To handle this, the nft_strtoi() helper fuction is included. I've changed some MXML_DESCEND[_FIRST] flags to avoid match a nested node under some circumstances, ie, matching two nodes with the same name that are descendant. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c
index be1b5d8..4a0bb9c 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -14,6 +14,8 @@
#include <limits.h>
#include <stdint.h>
#include <arpa/inet.h>
+#include <errno.h>
+#include <inttypes.h>
const char *nft_family2str(uint32_t family)
{
@@ -44,3 +46,74 @@ int nft_str2family(const char *family)
return -1;
}
+
+static struct {
+ int len;
+ int64_t min;
+ uint64_t max;
+} basetype[] = {
+ [NFT_TYPE_U8] = { .len = sizeof(uint8_t), .max = UINT8_MAX },
+ [NFT_TYPE_U16] = { .len = sizeof(uint16_t), .max = UINT16_MAX },
+ [NFT_TYPE_U32] = { .len = sizeof(uint32_t), .max = UINT32_MAX },
+ [NFT_TYPE_U64] = { .len = sizeof(uint64_t), .max = UINT64_MAX },
+ [NFT_TYPE_S8] = { .len = sizeof(int8_t), .min = INT8_MIN, .max = INT8_MAX },
+ [NFT_TYPE_S16] = { .len = sizeof(int16_t), .min = INT16_MIN, .max = INT16_MAX },
+ [NFT_TYPE_S32] = { .len = sizeof(int32_t), .min = INT32_MIN, .max = INT32_MAX },
+ [NFT_TYPE_S64] = { .len = sizeof(int64_t), .min = INT64_MIN, .max = INT64_MAX },
+};
+
+int nft_strtoi(const char *string, int base, void *out, enum nft_type type)
+{
+ int64_t sval = 0;
+ uint64_t uval = -1;
+ char *endptr;
+
+ switch (type) {
+ case NFT_TYPE_U8:
+ case NFT_TYPE_U16:
+ case NFT_TYPE_U32:
+ case NFT_TYPE_U64:
+ uval = strtoll(string, &endptr, base);
+ break;
+ case NFT_TYPE_S8:
+ case NFT_TYPE_S16:
+ case NFT_TYPE_S32:
+ case NFT_TYPE_S64:
+ sval = strtoull(string, &endptr, base);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*endptr) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ switch (type) {
+ case NFT_TYPE_U8:
+ case NFT_TYPE_U16:
+ case NFT_TYPE_U32:
+ case NFT_TYPE_U64:
+ if (uval > basetype[type].max) {
+ errno = ERANGE;
+ return -1;
+ }
+ memcpy(out, &uval, basetype[type].len);
+ break;
+ case NFT_TYPE_S8:
+ case NFT_TYPE_S16:
+ case NFT_TYPE_S32:
+ case NFT_TYPE_S64:
+ if (sval < basetype[type].min ||
+ sval > (int64_t)basetype[type].max) {
+ errno = ERANGE;
+ return -1;
+ }
+ memcpy(out, &sval, basetype[type].len);
+ break;
+ }
+
+ return 0;
+}