* [PATCH nft RFC] datatype: add time type parser and adapt output
@ 2014-01-16 21:01 Pablo Neira Ayuso
2014-01-16 21:05 ` Patrick McHardy
0 siblings, 1 reply; 3+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-16 21:01 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber
This patch allows to specify a string to indicate the time, eg.
nft add rule filter output ct expiration \"1d2h3m4s\" counter
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
An alternative to this patch is to use seconds as input/output, that only
needs a smaller patch to fix time_type_print().
include/utils.h | 4 ++
src/datatype.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 121 insertions(+), 16 deletions(-)
diff --git a/include/utils.h b/include/utils.h
index 854986f..f23f8e6 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -62,6 +62,10 @@
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof((a)[0]))
+#endif
+
extern void memory_allocation_error(void) __noreturn;
extern void xfree(const void *ptr);
diff --git a/src/datatype.c b/src/datatype.c
index 4594490..0541fc0 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>
@@ -670,7 +671,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);
@@ -683,22 +683,122 @@ 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, k = 0, len;
+ 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 = {
@@ -709,6 +809,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,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH nft RFC] datatype: add time type parser and adapt output
2014-01-16 21:01 [PATCH nft RFC] datatype: add time type parser and adapt output Pablo Neira Ayuso
@ 2014-01-16 21:05 ` Patrick McHardy
2014-01-16 21:23 ` Patrick McHardy
0 siblings, 1 reply; 3+ messages in thread
From: Patrick McHardy @ 2014-01-16 21:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Thu, Jan 16, 2014 at 10:01:02PM +0100, Pablo Neira Ayuso wrote:
> This patch allows to specify a string to indicate the time, eg.
>
> nft add rule filter output ct expiration \"1d2h3m4s\" counter
>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> An alternative to this patch is to use seconds as input/output, that only
> needs a smaller patch to fix time_type_print().
I think this is a much more natural way to specify relative times.
> include/utils.h | 4 ++
> src/datatype.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++-------
> 2 files changed, 121 insertions(+), 16 deletions(-)
>
> diff --git a/include/utils.h b/include/utils.h
> index 854986f..f23f8e6 100644
> --- a/include/utils.h
> +++ b/include/utils.h
> @@ -62,6 +62,10 @@
> (void) (&_max1 == &_max2); \
> _max1 > _max2 ? _max1 : _max2; })
>
> +#ifndef ARRAY_SIZE
> +#define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof((a)[0]))
> +#endif
We have array_size().
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH nft RFC] datatype: add time type parser and adapt output
2014-01-16 21:05 ` Patrick McHardy
@ 2014-01-16 21:23 ` Patrick McHardy
0 siblings, 0 replies; 3+ messages in thread
From: Patrick McHardy @ 2014-01-16 21:23 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Patrick McHardy <kaber@trash.net> schrieb:
>On Thu, Jan 16, 2014 at 10:01:02PM +0100, Pablo Neira Ayuso wrote:
>> This patch allows to specify a string to indicate the time, eg.
>>
>> nft add rule filter output ct expiration \"1d2h3m4s\" counter
>>
>> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>> ---
>> An alternative to this patch is to use seconds as input/output, that
>only
>> needs a smaller patch to fix time_type_print().
>
>I think this is a much more natural way to specify relative times.
Sorry, just realized that this was very much imprecise, I meant your patch oft course.
>
>> include/utils.h | 4 ++
>> src/datatype.c | 133
>++++++++++++++++++++++++++++++++++++++++++++++++-------
>> 2 files changed, 121 insertions(+), 16 deletions(-)
>>
>> diff --git a/include/utils.h b/include/utils.h
>> index 854986f..f23f8e6 100644
>> --- a/include/utils.h
>> +++ b/include/utils.h
>> @@ -62,6 +62,10 @@
>> (void) (&_max1 == &_max2); \
>> _max1 > _max2 ? _max1 : _max2; })
>>
>> +#ifndef ARRAY_SIZE
>> +#define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof((a)[0]))
>> +#endif
>
>We have array_size().
>--
>To unsubscribe from this list: send the line "unsubscribe
>netfilter-devel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-01-16 21:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-16 21:01 [PATCH nft RFC] datatype: add time type parser and adapt output Pablo Neira Ayuso
2014-01-16 21:05 ` Patrick McHardy
2014-01-16 21:23 ` Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.