summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/datatype.c134
-rw-r--r--src/mnl.c12
-rw-r--r--src/netlink.c8
3 files changed, 128 insertions, 26 deletions
diff --git a/src/datatype.c b/src/datatype.c
index 5e4aacdf..7c287bdf 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
+#include <ctype.h> /* isdigit */
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
@@ -688,7 +689,6 @@ const struct datatype mark_type = {
static void time_type_print(const struct expr *expr)
{
uint64_t days, hours, minutes, seconds;
- const char *delim = "";
seconds = mpz_get_uint64(expr->value);
@@ -701,22 +701,123 @@ static void time_type_print(const struct expr *expr)
minutes = seconds / 60;
seconds %= 60;
- if (days > 0) {
- printf("%s%" PRIu64 " d", delim, days);
- delim = " ";
- }
- if (hours > 0) {
- printf("%s%" PRIu64 " h", delim, hours);
- delim = " ";
- }
- if (minutes > 0) {
- printf("%s%" PRIu64 " min", delim, minutes);
- delim = " ";
- }
- if (seconds > 0) {
- printf("%s%" PRIu64 " s", delim, seconds);
- delim = " ";
+ printf("\"");
+
+ if (days > 0)
+ printf("%"PRIu64"d", days);
+ if (hours > 0)
+ printf("%"PRIu64"h", hours);
+ if (minutes > 0)
+ printf("%"PRIu64"m", minutes);
+ if (seconds > 0)
+ printf("%"PRIu64"s", seconds);
+
+ printf("\"");
+}
+
+enum {
+ DAY = (1 << 0),
+ HOUR = (1 << 1),
+ MIN = (1 << 2),
+ SECS = (1 << 3),
+};
+
+static uint32_t str2int(char *tmp, const char *c, int k)
+{
+ if (k == 0)
+ return 0;
+
+ strncpy(tmp, c-k, k+1);
+ return atoi(tmp);
+}
+
+static struct error_record *time_type_parse(const struct expr *sym,
+ struct expr **res)
+{
+ int i, len;
+ unsigned int k = 0;
+ char tmp[8];
+ const char *c;
+ uint64_t d = 0, h = 0, m = 0, s = 0;
+ uint32_t mask = 0;
+
+ c = sym->identifier;
+ len = strlen(c);
+ for (i = 0; i < len; i++, c++) {
+ switch (*c) {
+ case 'd':
+ if (mask & DAY) {
+ return error(&sym->location,
+ "Day has been specified twice");
+ }
+ d = str2int(tmp, c, k);
+ k = 0;
+ mask |= DAY;
+ break;
+ case 'h':
+ if (mask & HOUR) {
+ return error(&sym->location,
+ "Hour has been specified twice");
+ }
+ h = str2int(tmp, c, k);
+ k = 0;
+ if (h > 23) {
+ return error(&sym->location,
+ "Hour needs to be 0-23");
+ }
+ mask |= HOUR;
+ break;
+ case 'm':
+ if (mask & MIN) {
+ return error(&sym->location,
+ "Minute has been specified twice");
+ }
+ m = str2int(tmp, c, k);
+ k = 0;
+ if (m > 59) {
+ return error(&sym->location,
+ "Minute needs to be 0-59");
+ }
+ mask |= MIN;
+ break;
+ case 's':
+ if (mask & SECS) {
+ return error(&sym->location,
+ "Second has been specified twice");
+ }
+ s = str2int(tmp, c, k);
+ k = 0;
+ if (s > 59) {
+ return error(&sym->location,
+ "second needs to be 0-59");
+ }
+ mask |= SECS;
+ break;
+ default:
+ if (!isdigit(*c))
+ return error(&sym->location, "wrong format");
+
+ if (k++ >= array_size(tmp)) {
+ return error(&sym->location,
+ "value too large");
+ }
+ break;
+ }
}
+
+ /* default to seconds if no unit was specified */
+ if (!mask)
+ s = atoi(sym->identifier);
+ else
+ s = 24*60*60*d+60*60*h+60*m+s;
+
+ if (s > UINT32_MAX)
+ return error(&sym->location, "value too large");
+
+ *res = constant_expr_alloc(&sym->location, &time_type,
+ BYTEORDER_HOST_ENDIAN,
+ sizeof(uint32_t) * BITS_PER_BYTE, &s);
+ return NULL;
}
const struct datatype time_type = {
@@ -727,6 +828,7 @@ const struct datatype time_type = {
.size = 8 * BITS_PER_BYTE,
.basetype = &integer_type,
.print = time_type_print,
+ .parse = time_type_parse,
};
static struct error_record *concat_type_parse(const struct expr *sym,
diff --git a/src/mnl.c b/src/mnl.c
index 16625000..b8679022 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -9,11 +9,11 @@
*/
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
-#include <libnftables/set.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/set.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
@@ -394,7 +394,7 @@ int mnl_nft_chain_add(struct mnl_socket *nf_sock, struct nft_chain *nlc,
nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN,
nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_FAMILY),
- NLM_F_ACK|flags, seq);
+ NLM_F_CREATE|NLM_F_ACK|flags, seq);
nft_chain_nlmsg_build_payload(nlh, nlc);
return mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
diff --git a/src/netlink.c b/src/netlink.c
index b776b3cc..7f69995d 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -14,10 +14,10 @@
#include <errno.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-#include <libnftables/expr.h>
-#include <libnftables/set.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/set.h>
#include <linux/netfilter/nf_tables.h>
#include <nftables.h>