All of lore.kernel.org
 help / color / mirror / Atom feed
* nfsim updates
@ 2004-09-19 22:34 Harald Welte
  2004-09-21  2:13 ` Rusty Russell
  0 siblings, 1 reply; 5+ messages in thread
From: Harald Welte @ 2004-09-19 22:34 UTC (permalink / raw)
  To: jk, Rusty Russell; +Cc: Netfilter Development Mailinglist

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

Hi!

I was actually over the last days using nfsim for useful debugging the
first time :)

Please review (+ integrate?) the following changes:

1) add open/fopen support to fakesockopt (for iptables-save)
2) block SIGCHILD in message.c (if exec()ed program dies)
3) fix wrong "((len = read(fd, msg, sizeof(*msg)) != sizeof(*msg)))"
4) add iptables-save and iptables-restore as commands

I've also started some early (boring) ipv6 support work, but it turned
out to be more time consuming than I though :(  I'll try to finish this
at some point, though.

btw: Could you please make your current SVN tree publicly accessible at
some point?  As stated before, we could also move it to
svn.netfilter.org (which actually exists, but also has no public
interface yet).

- Harald


diff -Nru nfsim-20040907-plain/core/fakesockopt.c nfsim-20040907-laf/core/fakesockopt.c
--- nfsim-20040907-plain/core/fakesockopt.c	2004-03-01 07:26:37.000000000 +0100
+++ nfsim-20040907-laf/core/fakesockopt.c	2004-09-20 00:27:58.000000000 +0200
@@ -1,6 +1,6 @@
 /*
 
-Copyright (c) 2003,2004 Jeremy Kerr & Rusty Russell
+Copyright (c) 2003,2004 Jeremy Kerr, Rusty Russell & Harald Welte
 
 This file is part of nfsim.
 
@@ -33,21 +33,28 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
+
 #include <dlfcn.h>
 
 #include <assert.h>
 #include <string.h>
 
+#include <netinet/in.h>
+
 /* pointers to the real functions */
 static int (*__socket)(int, int, int);
 static int (*__getsockopt)(int, int , int , void *, socklen_t *);
 static int (*__setsockopt)(int, int , int , void *, socklen_t *);
+static int (*__open)(const char *pathname, int flags, ...);
+FILE * (*__fopen)(const char *path, const char *mode);
 static int (*__close)(int);
 
 static int sd;
 static void *handle;
+static char *proc_prefix = "/tmp/nfsim/proc";
 
 #undef DEBUG
+#define DEBUG
 
 /* utils expects a log function.  Give it to them. */
 void nfsim_log(enum log_type type, const char *fmt, ...)
@@ -81,6 +88,7 @@
 {
 	struct sockaddr_un unix_addr;
 	int addrlen;
+	char *prefix;
 
 	if (!(handle = dlopen("libc.so.6", RTLD_LAZY))) {
 		fprintf(stderr, "%s\n", dlerror());
@@ -90,6 +98,8 @@
 	sym(handle, getsockopt);
 	sym(handle, setsockopt);
 	sym(handle, socket);
+	sym(handle, open);
+	sym(handle, fopen);
 	sym(handle, close);
 
 	dlclose(handle);
@@ -112,6 +122,10 @@
 		exit(EXIT_FAILURE);
 	}
 
+	prefix = getenv("NFSIM_PROC_PREFIX");
+	if (prefix)
+		proc_prefix = prefix;
+
 	return;
 
 }
@@ -254,9 +268,100 @@
 	printf("socket(%d, %d, %d)\n", domain, type, protocol);
 #endif /* DEBUG */
 
-	return sd;
+	/* only catch AF_INET/SOCK_RAW/IPPROTO_RAW sockets */
+	if (domain == AF_INET && type == SOCK_RAW && protocol == IPPROTO_RAW)
+		return sd;
+	//else if (domain == AF_NETLINK)
+	//	return fake_netlink_socket(domain, type, protocol);
+	else
+		return __socket(domain, type, protocol);
+}
+
+
+static int file_is_proc(const char *pathname)
+{
+	if (pathname && strlen(pathname) >= 6 
+	    && !strncmp(pathname, "/proc/", 6))
+		return 1;
+	else
+		return 0;
+}
+
+static char *mangle_alloc_proc_path(const char *pathname)
+{
+	char *fakepath = (char *) malloc(strlen(pathname) 
+			 + strlen(proc_prefix));
+	if (!fakepath)
+		return NULL;
+
+	strcpy(fakepath, proc_prefix);
+	strcat(fakepath, pathname+5); /* 5 because '/' */
+
+	return fakepath;
 }
 
+
+/* open intercepts any accesses to /proc and directs them to somewhere else */
+int open(const char *pathname, int flags, ...)
+{
+	int ret;
+	va_list arglist;
+	mode_t mode = 0;
+
+#ifdef DEBUG
+	printf("open(%s, %d)\n", pathname, flags);
+#endif
+
+	va_start(arglist, flags);
+
+	/* mode is only valid if O_CREAT was specified */
+	if (flags & O_CREAT)
+		mode = va_arg(arglist, mode_t);
+
+	/* if this is not a /proc open, pass it through */
+	if (!file_is_proc(pathname))
+		ret = __open(pathname, flags, mode);
+	else {
+		char *fakepath = mangle_alloc_proc_path(pathname);
+		if (!fakepath) {
+			ret = -ENOMEM;
+			/* need this ugly goto for va_end */
+			goto out;
+		}
+
+		/* mode will be ignored in case of no O_CRAT */
+		ret = __open(fakepath, flags, mode);
+
+		free(fakepath);
+	}
+out:
+	va_end(arglist);
+	return ret;
+}
+
+FILE *fopen(const char *path, const char *mode)
+{
+	FILE *ret;
+
+#ifdef DEBUG
+	printf("%s(%s, %s)\n", __FUNCTION__, path, mode);
+#endif
+
+	if (!file_is_proc(path))
+		ret = __fopen(path, mode);
+	else {
+		char *fakepath = mangle_alloc_proc_path(path);
+		if (!fakepath) {
+			errno = -ENOMEM;
+			return NULL;
+		}
+
+		ret = __fopen(fakepath, mode);
+	}
+	return ret;
+}
+
+
 int close(int fd)
 {
 	return (fd == sd) ? 0 : (*__close)(fd);
diff -Nru nfsim-20040907-plain/core/message.c nfsim-20040907-laf/core/message.c
--- nfsim-20040907-plain/core/message.c	2004-03-01 07:26:37.000000000 +0100
+++ nfsim-20040907-laf/core/message.c	2004-09-19 22:11:00.000000000 +0200
@@ -22,6 +22,7 @@
 #include "message.h"
 #include "utils.h"
 
+#include <signal.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -35,6 +36,7 @@
 void message_init(void)
 {
 	struct sockaddr_un unix_addr;
+	sigset_t ss;
 
 	unlink(FAKE_SOCKET);
 
@@ -51,11 +53,21 @@
 
 	if (listen(sockfd, 0))
 		barf_perror("listen");
+
+	sigemptyset(&ss);
+	sigaddset(&ss, SIGPIPE);
+	sigprocmask(SIG_BLOCK, &ss, NULL);
 }
 
 void message_cleanup(void)
 {
+	sigset_t ss;
+
 	close(sockfd);
+
+	sigemptyset(&ss);
+	sigaddset(&ss, SIGPIPE);
+	sigprocmask(SIG_UNBLOCK, &ss, NULL);
 }
 
 int message_client_connection(int fd)
@@ -80,10 +92,12 @@
 	struct nf_userspace_message *msg;
 
 	msg = new(struct nf_userspace_message);
-	if ((len = read(fd, msg, sizeof(*msg)) != sizeof(*msg))) {
+	len = read(fd, msg, sizeof(*msg));
+	if (len != sizeof(*msg)) {
 		free(msg);
 		return -1;
 	}
+	fprintf(stderr, "%s: received %u bytes\n", __FUNCTION__, len);
 
 	if (msg->type == UM_SYSCALL) {
 		switch (msg->opcode) {
@@ -122,7 +136,7 @@
 				msg->opcode);
 		}
 	} else {
-		fprintf(stderr, "Unknown message type\n");
+		fprintf(stderr, "Unknown message type %d\n", msg->type);
 	}
 
 	free(msg);
diff -Nru nfsim-20040907-plain/tools/iptables.c nfsim-20040907-laf/tools/iptables.c
--- nfsim-20040907-plain/tools/iptables.c	2004-03-01 07:26:29.000000000 +0100
+++ nfsim-20040907-laf/tools/iptables.c	2004-09-19 22:11:27.000000000 +0200
@@ -1,6 +1,6 @@
 /*
 
-Copyright (c) 2003,2004 Jeremy Kerr & Rusty Russell
+Copyright (c) 2003,2004 Jeremy Kerr, Rusty Russell and Harald Welte
 
 This file is part of nfsim.
 
@@ -24,6 +24,7 @@
 #include <ipv4/ipv4.h>
 
 #include <unistd.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <signal.h>
@@ -31,36 +32,46 @@
 #include "message.h"
 
 static int sigfd[2];
+static char *iptables_prefix = "/sbin";
 
 static void wake_parent(int signum)
 {
 	write(sigfd[1], "", 1);
 }
 
-static bool iptables(int argc, char **argv)
+static bool xtables_x(int argc, char **argv)
 {
 	pid_t child;
 	int status;
+	int cmdlen = strlen(argv[0]) + strlen(iptables_prefix) + 2;
+	char *cmd = malloc(cmdlen);
+
+	if (!cmd)
+		barf_perror("%s: ENOMEM", argv[0]);
+
+	strcpy(cmd, iptables_prefix);
+	strcat(cmd, "/");
+	strcat(cmd, argv[0]);
 
 	if (pipe(sigfd) != 0)
-		barf_perror("iptables pipe");
+		barf_perror("%s pipe", argv[0]);
 
 	signal(SIGCHLD, wake_parent);
-	
+
 	child = fork();
 	switch (child) {
 	case -1:
-		barf_perror("iptables fork");
+		barf_perror("%s fork", argv[0]);
 	case 0:
 		if (setenv("LD_PRELOAD", "core/fakesockopt.so.1.0", 1))
 			barf("putenv failed");
-		execv("/sbin/iptables", argv);
+		execv(cmd, argv);
 		exit(1);
 	}
 
 	wait_for_message(sigfd[0]);
 	if (waitpid(child, &status, WNOHANG) <= 0)
-		barf_perror("Waiting for iptables child");
+		barf_perror("Waiting for %s child", argv[0]);
 
 	close(sigfd[0]);
 	close(sigfd[1]);
@@ -70,16 +81,29 @@
 	return false;
 }
 
-static void iptables_help(int argc, char **argv)
+static void xtables_x_help(int argc, char **argv)
 {
-	nfsim_log(LOG_ALWAYS, "iptables <arguments>\n"
-		"\trun iptables (on the simulated netfilter code), with the\n"
-		"\tspecified arguments");
+	nfsim_log(LOG_ALWAYS, "%s <arguments>\n"
+		"\trun %s (on the simulated netfilter code), with the\n"
+		"\tspecified arguments", argv[0]);
 }
 
 static int init(void)
 {
-	tui_register_command("iptables", iptables, iptables_help);
+	char *prefix = getenv("NFSIM_IPTABLES_PREFIX");
+	if (prefix)
+		iptables_prefix = prefix;
+
+	tui_register_command("iptables", xtables_x, xtables_x_help);
+	tui_register_command("iptables-save", xtables_x, xtables_x_help);
+	tui_register_command("iptables-restore", xtables_x, xtables_x_help);
+
+#ifdef HAVE_IPV6
+	tui_register_command("ip6tables", xtables_x, xtables_x_help);
+	tui_register_command("ip6tables-save", xtables_x, xtables_x_help);
+	tui_register_command("ip6tables-restore", xtables_x, xtables_x_help);
+#endif
+
 	return 0;
 }
 


-- 
- Harald Welte <laforge@netfilter.org>             http://www.netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-09-25  7:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-19 22:34 nfsim updates Harald Welte
2004-09-21  2:13 ` Rusty Russell
2004-09-23  1:04   ` Jeremy Kerr
2004-09-23 12:41     ` Eric Leblond
2004-09-25  7:00     ` Harald Welte

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.