All of lore.kernel.org
 help / color / mirror / Atom feed
From: Phil Oester <kernel@linuxace.com>
To: netfilter-devel@lists.netfilter.org
Subject: [PATCH] resend: Refuse multiple --to args in [DS]NAT
Date: Sun, 18 Sep 2005 10:13:23 -0700	[thread overview]
Message-ID: <20050918171323.GB19936@linuxace.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 843 bytes --]

Didn't receive any feedback on the below.  If I don't hear anything,
I'll assume no interest and drop it.

***

Kernels higher than 2.6.10 don't support multiple --to arguments in
DNAT and SNAT targets.  At present, the error is somewhat vague:

# iptables -t nat -A foo -j SNAT --to 1.2.3.4 --to 2.3.4.5
iptables: Invalid argument

But if we want current iptables to work with kernels <= 2.6.10, we
cannot simply disallow this in all cases.

So the below patch adds kernel version checking to iptables, and
utilizes it in [DS]NAT.  Now, users will see a more informative error:

# iptables -t nat -A foo -j SNAT --to 1.2.3.4 --to 2.3.4.5
iptables v1.3.3: Multiple --to-source not supported

This generic infrastructure (shamelessly lifted from procps btw) may
come in handy in the future for other changes.

This fixes bugzilla #367.

Phil



[-- Attachment #2: patch-multiple_to --]
[-- Type: text/plain, Size: 3017 bytes --]

diff -ru ipt-orig/extensions/libipt_DNAT.c ipt-new/extensions/libipt_DNAT.c
--- ipt-orig/extensions/libipt_DNAT.c	2005-07-22 05:13:50.000000000 -0700
+++ ipt-new/extensions/libipt_DNAT.c	2005-09-04 10:46:28.000000000 -0700
@@ -155,6 +155,13 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to-destination");
 
+		if (*flags) {
+			if (!kernel_version)
+				get_kernel_version();
+			if (kernel_version > LINUX_VERSION(2, 6, 10))
+				exit_error(PARAMETER_PROBLEM,
+					   "Multiple --to-destination not supported");
+		}
 		*target = parse_to(optarg, portok, info);
 		*flags = 1;
 		return 1;
diff -ru ipt-orig/extensions/libipt_SNAT.c ipt-new/extensions/libipt_SNAT.c
--- ipt-orig/extensions/libipt_SNAT.c	2005-07-22 05:13:50.000000000 -0700
+++ ipt-new/extensions/libipt_SNAT.c	2005-09-04 12:28:07.000000000 -0700
@@ -155,6 +155,13 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Unexpected `!' after --to-source");
 
+		if (*flags) {
+			if (!kernel_version)
+				get_kernel_version();
+			if (kernel_version > LINUX_VERSION(2, 6, 10))
+				exit_error(PARAMETER_PROBLEM,
+					   "Multiple --to-source not supported");
+		}
 		*target = parse_to(optarg, portok, info);
 		*flags = 1;
 		return 1;
diff -ru ipt-orig/include/iptables.h ipt-new/include/iptables.h
--- ipt-orig/include/iptables.h	2005-07-04 15:11:28.000000000 -0700
+++ ipt-new/include/iptables.h	2005-09-04 10:31:43.000000000 -0700
@@ -175,4 +175,13 @@
 			iptc_handle_t *handle);
 extern int for_each_chain(int (*fn)(const ipt_chainlabel, int, iptc_handle_t *),
 		int verbose, int builtinstoo, iptc_handle_t *handle);
+
+/* kernel revision handling */
+extern int kernel_version;
+extern void get_kernel_version(void);
+#define LINUX_VERSION(x,y,z)	(0x10000*(x) + 0x100*(y) + z)
+#define LINUX_VERSION_MAJOR(x)	(((x)>>16) & 0xFF)
+#define LINUX_VERSION_MINOR(x)	(((x)>> 8) & 0xFF)
+#define LINUX_VERSION_PATCH(x)	( (x)      & 0xFF)
+
 #endif /*_IPTABLES_USER_H*/
diff -ru ipt-orig/iptables.c ipt-new/iptables.c
--- ipt-orig/iptables.c	2005-07-29 06:06:45.000000000 -0700
+++ ipt-new/iptables.c	2005-09-04 10:38:19.000000000 -0700
@@ -39,6 +39,7 @@
 #include <iptables.h>
 #include <fcntl.h>
 #include <sys/wait.h>
+#include <sys/utsname.h>
 
 #ifndef TRUE
 #define TRUE 1
@@ -193,6 +194,8 @@
 const char *program_name;
 char *lib_dir;
 
+int kernel_version;
+
 /* Keeping track of external matches and targets: linked lists.  */
 struct iptables_match *iptables_matches = NULL;
 struct iptables_target *iptables_targets = NULL;
@@ -1804,6 +1807,21 @@
 	name[IPT_FUNCTION_MAXNAMELEN - 1] = revision;
 }
 
+void
+get_kernel_version(void) {
+	static struct utsname uts;
+	int x = 0, y = 0, z = 0;
+
+	if (uname(&uts) == -1) {
+		fprintf(stderr, "Unable to retrieve kernel version.\n");
+		free_opts(1);
+		exit(1); 
+	}
+
+	sscanf(uts.release, "%d.%d.%d", &x, &y, &z);
+	kernel_version = LINUX_VERSION(x, y, z);
+}
+
 int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
 {
 	struct ipt_entry fw, *e = NULL;

                 reply	other threads:[~2005-09-18 17:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050918171323.GB19936@linuxace.com \
    --to=kernel@linuxace.com \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.