Hi,

Another patch.  This patch executes a configuration script after
initialising the TAP device.  The script is /etc/rpcemu/ifup.sh, and is
passed 3 arguments: TAP device name, ip address and netmask.  The patch
was inspired by qemu.

An example script is in src/script/linux.  This should perform the steps
as set out in the Wiki entry on riscos.info in a fairly generic way.

Obviously, processes owned by root spawning scripts can lead to a whole
load of security issues, but I think if we have a script that is owned
by root, and and be written to by root only, then we should not have too
many issues.

Hope it helps.

James
Index: network-linux.c
===================================================================
--- network-linux.c	(revision 137)
+++ network-linux.c	(working copy)
@@ -7,6 +7,7 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
+#include <sys/wait.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/socket.h>
@@ -22,6 +23,9 @@
 #include "mem.h"
 #include "podules.h"
 
+#define SCRIPT_NAME "ifup.sh"
+#define SCRIPT_PATH "/etc/rpcemu/" SCRIPT_NAME
+
 /* The opened tunnel device */
 static int tunfd = -1;
 
@@ -83,11 +87,53 @@
         return 0;
 }
 
+static int exec_script(const char *device, const char *ipaddress, const int netmask)
+{
+    int pid = 0;
+    int status = 0;
+    char mask[10];
+
+    snprintf(mask, sizeof(mask), "%d", netmask);
+    if ((pid = fork()) == 0) {
+        /* This script is going to be executed by root, so the script
+         * should be writable by root only to ensure that
+         * there are no security issues */
+        execl(SCRIPT_PATH, SCRIPT_NAME, device, ipaddress, mask, NULL);
+		return 1;
+    } else {
+        waitpid(pid, &status, 0);
+    }
+
+    return status;
+}
+
+int get_netmask(int sd, struct ifreq *ifr)
+{
+    int netmask = 0;
+    unsigned int i;
+    int mask;
+
+    if (ioctl(sd, SIOCGIFNETMASK, ifr) < 0) {
+        printf("Error getting %s netmask %s\n", ifr->ifr_name, strerror(errno));
+        return 0;
+    } else {
+        mask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr;
+        for (i = 0; i < sizeof(mask) * 8; i++) {
+            if (mask & (1<<i)) {
+                netmask++;
+            }
+        }
+    }
+
+    return netmask;
+}
+
 /* Open and configure the tunnel device */
 static int tun_alloc(void)
 {
     struct ifreq ifr;
     struct sockaddr_in *addr;
+    int netmask;
     int fd;
     int sd;
     
@@ -140,8 +186,14 @@
         return -1;
     }
 
+    netmask = get_netmask(sd, &ifr);
+
     close(sd);
 
+    if (netmask) {
+        exec_script(ifr.ifr_name, ipaddress, netmask);
+    }
+
     if (fcntl(fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1) {
         printf("Error setting %s non-blocking: %s\n", ifr.ifr_name, strerror(errno));
         return -1;
Index: script/linux/ifup.sh
===================================================================
--- script/linux/ifup.sh	(revision 0)
+++ script/linux/ifup.sh	(revision 0)
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# arguments:
+# $1 = TAP device name
+# $2 = TAP device IP address
+# $3 = TAP device netmask
+
+main_device=eth0
+# which device does the default route go through
+if [ -e /sbin/ip ]; then
+	if /sbin/ip route list | grep ^default > /dev/null; then
+		main_device=`/sbin/ip route list | grep ^default | cut -d ' ' -f 5`
+	fi
+else
+	if /sbin/route -n | grep "^0.0.0.0 > /dev/null"; then
+		main_device=`/sbin/route -n | grep ^0.0.0.0 | cut -c 73-`
+	fi
+fi
+
+# if the iptables rules don't exist, then add them
+if ! /sbin/iptables -L FORWARD -m state --state ESTABLISHED,RELATED | grep ^ACCEPT > /dev/null ; then
+	/sbin/iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
+fi
+# we can't to an -L on the next chain, which is a shame.
+/sbin/iptables -t nat -D POSTROUTING --source $2/$3 -o $main_device -j MASQUERADE 2>&1 | grep -v "No chain/target/match"
+/sbin/iptables -t nat -A POSTROUTING --source $2/$3 -o $main_device -j MASQUERADE
+
+echo 1 > /proc/sys/net/ipv4/ip_forward
+echo 1 > /proc/sys/net/ipv4/ip_dynaddr
+

Property changes on: script/linux/ifup.sh
___________________________________________________________________
Name: svn:executable
   + *

_______________________________________________
Rpcemu mailing list
[email protected]
http://www.riscos.info/cgi-bin/mailman/listinfo/rpcemu

Reply via email to