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