diff mbox series

[iptables] extensions: time: add translation and tests

Message ID 20200204102416.981-1-guigom@riseup.net
State Accepted
Headers show
Series [iptables] extensions: time: add translation and tests | expand

Commit Message

Jose M. Guisado Gomez Feb. 4, 2020, 10:24 a.m. UTC
Translation capabilities for xtables time match. Different time values
(hour and datetime) are translated into ranges.

These time match options can be translated now

	--timestart value
	--timestop value
	[!] --weekdays listofdays
	--datestart date
	--datestop date

The option --monthdays can't be translated into nft as of now.

Examples can be found inside libxt_time.txlate

Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
---
 extensions/libxt_time.c      | 72 ++++++++++++++++++++++++++++++++++++
 extensions/libxt_time.txlate | 26 +++++++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 extensions/libxt_time.txlate

Comments

Florian Westphal Feb. 4, 2020, 10:40 a.m. UTC | #1
Jose M. Guisado Gomez <guigom@riseup.net> wrote:
> Translation capabilities for xtables time match. Different time values
> (hour and datetime) are translated into ranges.
> 
> These time match options can be translated now
> 
> 	--timestart value
> 	--timestop value
> 	[!] --weekdays listofdays
> 	--datestart date
> 	--datestop date
> 
> The option --monthdays can't be translated into nft as of now.
> 
> Examples can be found inside libxt_time.txlate

Looks good, I've pushed this to iptables.git.

Thanks!
diff mbox series

Patch

diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c
index d001f5b7..d27d84ca 100644
--- a/extensions/libxt_time.c
+++ b/extensions/libxt_time.c
@@ -258,6 +258,16 @@  static unsigned int time_parse_weekdays(const char *arg)
 	return ret;
 }
 
+static unsigned int time_count_weekdays(unsigned int weekdays_mask)
+{
+	unsigned int ret;
+
+	for (ret = 0; weekdays_mask; weekdays_mask >>= 1)
+		ret += weekdays_mask & 1;
+
+	return ret;
+}
+
 static void time_parse(struct xt_option_call *cb)
 {
 	struct xt_time_info *info = cb->data;
@@ -450,6 +460,67 @@  static void time_check(struct xt_fcheck_call *cb)
 			"time: --contiguous only makes sense when stoptime is smaller than starttime");
 }
 
+static int time_xlate(struct xt_xlate *xl,
+		      const struct xt_xlate_mt_params *params)
+{
+	const struct xt_time_info *info =
+		(const struct xt_time_info *)params->match->data;
+	unsigned int h, m, s,
+		     i, sep, mask, count;
+	time_t tt_start, tt_stop;
+	struct tm *t_start, *t_stop;
+
+	if (info->date_start != 0 ||
+	    info->date_stop != INT_MAX) {
+		tt_start = (time_t) info->date_start;
+		tt_stop = (time_t) info->date_stop;
+
+		xt_xlate_add(xl, "meta time ");
+		t_start = gmtime(&tt_start);
+		xt_xlate_add(xl, "\"%04u-%02u-%02u %02u:%02u:%02u\"",
+			     t_start->tm_year + 1900, t_start->tm_mon + 1,
+			     t_start->tm_mday, t_start->tm_hour,
+			     t_start->tm_min, t_start->tm_sec);
+		t_stop = gmtime(&tt_stop);
+		xt_xlate_add(xl, "-\"%04u-%02u-%02u %02u:%02u:%02u\"",
+			     t_stop->tm_year + 1900, t_stop->tm_mon + 1,
+			     t_stop->tm_mday, t_stop->tm_hour,
+			     t_stop->tm_min, t_stop->tm_sec);
+	}
+	if (info->daytime_start != XT_TIME_MIN_DAYTIME ||
+	    info->daytime_stop != XT_TIME_MAX_DAYTIME) {
+		divide_time(info->daytime_start, &h, &m, &s);
+		xt_xlate_add(xl, " meta hour \"%02u:%02u:%02u\"", h, m, s);
+		divide_time(info->daytime_stop, &h, &m, &s);
+		xt_xlate_add(xl, "-\"%02u:%02u:%02u\"", h, m, s);
+	}
+	/* nft_time does not support --monthdays */
+	if (info->monthdays_match != XT_TIME_ALL_MONTHDAYS)
+		return 0;
+	if (info->weekdays_match != XT_TIME_ALL_WEEKDAYS) {
+		sep = 0;
+		mask = info->weekdays_match;
+		count = time_count_weekdays(mask);
+
+		xt_xlate_add(xl, " meta day ");
+		if (count > 1)
+			xt_xlate_add(xl, "{");
+		for (i = 1; i <= 7; ++i)
+			if (mask & (1 << i)) {
+				if (sep)
+					xt_xlate_add(xl, ",%u", i%7);
+				else {
+					xt_xlate_add(xl, "%u", i%7);
+					++sep;
+				}
+			}
+		if (count > 1)
+			xt_xlate_add(xl, "}");
+	}
+
+	return 1;
+}
+
 static struct xtables_match time_match = {
 	.name          = "time",
 	.family        = NFPROTO_UNSPEC,
@@ -463,6 +534,7 @@  static struct xtables_match time_match = {
 	.x6_parse      = time_parse,
 	.x6_fcheck     = time_check,
 	.x6_options    = time_opts,
+	.xlate	       = time_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libxt_time.txlate b/extensions/libxt_time.txlate
new file mode 100644
index 00000000..ff4a7b88
--- /dev/null
+++ b/extensions/libxt_time.txlate
@@ -0,0 +1,26 @@ 
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --weekdays Sa,Su -j REJECT
+nft add rule ip filter INPUT icmp type echo-request  meta day {6,0} counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --timestart 12:00 -j REJECT
+nft add rule ip filter INPUT icmp type echo-request  meta hour "12:00:00"-"23:59:59" counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --timestop 12:00 -j REJECT
+nft add rule ip filter INPUT icmp type echo-request  meta hour "00:00:00"-"12:00:00" counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2021 -j REJECT
+nft add rule ip filter INPUT icmp type echo-request meta time "2021-01-01 00:00:00"-"2038-01-19 03:14:07" counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestop 2021 -j REJECT
+nft add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-01 00:00:00" counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestop 2021-01-29T00:00:00 -j REJECT
+nft add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-29 00:00:00" counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 -j REJECT
+nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"23:59:59" counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 --timestop 19:00 --weekdays Mon,Tue,Wed,Thu,Fri -j REJECT
+nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day {1,2,3,4,5} counter reject
+
+iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 --timestop 19:00 ! --weekdays Mon,Tue,Wed,Thu,Fri -j REJECT
+nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day {6,0} counter reject