Renamed files and comments to fit new project name
authorGregor Riepl <onitake@gmail.com>
Thu, 22 Jul 2010 17:10:10 +0000 (19:10 +0200)
committerGregor Riepl <onitake@gmail.com>
Thu, 22 Jul 2010 17:10:10 +0000 (19:10 +0200)
Fixed wrong dnsmasq command line in old tethering script

.gitignore
Makefile
device.c
device.h
event.d-maemo-tethering [deleted file]
event.d-mtetherd [new file with mode: 0644]
main.c [deleted file]
mtetherd.c [new file with mode: 0644]
tethering.sh

index 0001171..e87a6c7 100644 (file)
@@ -1,2 +1,2 @@
 *.o
-maemo-tethering
+mtetherd
index 5e7494f..d226f7a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,14 +8,14 @@ SSH_ADDRESS = developer@192.168.253.254
 SSH_SCP = scp
 SSH_SSH = ssh
 SSH_PATH = /home/developer
-DATA_FILES = main.c device.c device.h
+DATA_FILES = main.c device.c device.h event.d-mtetherd
 
-maemo-tethering: main.o device.o
+mtetherd: main.o device.o
        $(MAD) $(CC) $(LDFLAGS) $(LIBS) -o $@ $^
 
 %PHONY: copy run clean
 
-copy: maemo-tethering $(DATA_FILES)
+copy: mtetherd $(DATA_FILES)
        $(SSH_SCP) $^ $(SSH_ADDRESS):$(SSH_PATH)
 
 run: copy
index 7902ee4..022f8cb 100644 (file)
--- a/device.c
+++ b/device.c
@@ -1,5 +1,5 @@
 /*
-  maemo-tethering
+  mtetherd
   (c) 2010 Gregor Riepl <onitake@gmail.com>
   
   Tethering utility for Maemo
index 3a216f0..fe8c55c 100644 (file)
--- a/device.h
+++ b/device.h
@@ -1,5 +1,5 @@
 /*
-  maemo-tethering
+  mtetherd
   (c) 2010 Gregor Riepl <onitake@gmail.com>
   
   Tethering utility for Maemo
diff --git a/event.d-maemo-tethering b/event.d-maemo-tethering
deleted file mode 100644 (file)
index cf4dd9d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-description "maemo-tethering"
-author "Gregor Riepl <onitake@gmail.com>"
-
-start on started dbus
-stop on stopping dbus
-
-console none
-
-exec /usr/sbin/maemo-tethering
-
-respawn
-
diff --git a/event.d-mtetherd b/event.d-mtetherd
new file mode 100644 (file)
index 0000000..cf4dd9d
--- /dev/null
@@ -0,0 +1,12 @@
+description "maemo-tethering"
+author "Gregor Riepl <onitake@gmail.com>"
+
+start on started dbus
+stop on stopping dbus
+
+console none
+
+exec /usr/sbin/maemo-tethering
+
+respawn
+
diff --git a/main.c b/main.c
deleted file mode 100644 (file)
index d86ad4e..0000000
--- a/main.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
-  maemo-tethering
-  (c) 2010 Gregor Riepl <onitake@gmail.com>
-  
-  Tethering utility for Maemo
-  
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-  
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-  
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <sys/wait.h>
-#include <dbus/dbus.h>
-#include "device.h"
-
-static const char *INETDEV = "gprs0";
-static const char *DEVICES[] = {
-       "usb0",
-       "bnep0",
-       NULL
-};
-static const char *ADDRESSES[] = {
-       "192.168.253.254",
-       "192.168.254.254",
-       NULL
-};
-static const char *STARTADDRESSES[] = {
-       "192.168.253.1",
-       "192.168.254.1",
-       NULL
-};
-static const char *ENDADDRESSES[] = {
-       "192.168.253.254",
-       "192.168.254.254",
-       NULL
-};
-// Wait x seconds for process termination
-static const unsigned int TERMINATE_WAIT = 5;
-// Poll the main loop after x milliseconds
-static const unsigned int POLL_MAINLOOP = 500;
-
-// Run loop active flag
-static int running;
-// Number of active tethering connections
-static unsigned int active;
-
-static void siginthandler(int sig) {
-       if (running) {
-               fprintf(stderr, "SIGINIT received, exiting\n");
-               running = 0;
-       } else {
-               fprintf(stderr, "Another SIGINIT received, aborting\n");
-               if (kill(getpid(), SIGKILL) == -1) {
-                       fprintf(stderr, "PANIC! Error killing self: %s\n", strerror(errno));
-               }
-       }
-}
-
-static int launch(const char *args[]) {
-       pid_t pid = fork();
-       if (pid == 0) {
-               if (execv(args[0], (char **const) args) == -1) {
-                       fprintf(stderr, "Error launching external process %s: %s\n", args[0], strerror(errno));
-                       exit(1);
-               }
-       } else if (pid == -1) {
-               fprintf(stderr, "Can't fork external process %s: %s\n", args[0], strerror(errno));
-               return -1;
-       } else {
-               /*printf("Launching:");
-               size_t a;
-               for (a = 0; args[a]; a++) {
-                       printf(" %s", args[a]);
-               }
-               printf("\n");*/
-               int status = 0;
-               if (waitpid(pid, &status, WNOHANG) == -1) {
-                       fprintf(stderr, "Error waiting for child process completion: %s\n", strerror(errno));
-                       return -2;
-               }
-               size_t i;
-               for (i = 0; i < TERMINATE_WAIT && !WIFEXITED(status); i++) {
-                       if (WIFEXITED(status)) {
-                               if (WEXITSTATUS(status) != 0) {
-                                       fprintf(stderr, "Child process returned error: %d\n", WEXITSTATUS(status));
-                                       return -3;
-                               }
-                       } else if (WIFSIGNALED(status)) {
-                               fprintf(stderr, "Child process killed by signal: %d\n", WTERMSIG(status));
-                               return -4;
-                       }
-                       sleep(1);
-                       if (waitpid(pid, &status, WNOHANG) == -1) {
-                               fprintf(stderr, "Error waiting for child process completion: %s\n", strerror(errno));
-                               return -2;
-                       }
-               }
-               if (i >= TERMINATE_WAIT) {
-                       fprintf(stderr, "Child process %s still running after %u seconds, ignoring.\n", args[0], TERMINATE_WAIT);
-                       return -5;
-               }
-       }
-       return 0;
-}
-
-static void added(Device *device, const char *inetdev) {
-       printf("Got org.kernel.kevent.add on %s\n", device->name);
-       char *runfile = NULL;
-       if (asprintf(&runfile, "/var/run/tethering.%s.pid", device->name) == -1) {
-               fprintf(stderr, "Can't construct PID file name for device %s: %s\n", device->name, strerror(errno));
-               return;
-       }
-       char *range = NULL;
-       if (asprintf(&range, "%s,%s,3600", device->startaddress, device->endaddress) == -1) {
-               fprintf(stderr, "Can't construct address range parameter for device %s: %s\n", device->name, strerror(errno));
-               free(runfile);
-               return;
-       }
-       const char *ifconfig[] = { "/sbin/ifconfig", device->name, device->address, "up", NULL };
-       const char *modprobe[] = { "/sbin/modprobe", "ipt_MASQUERADE", NULL };
-       const char *iptables[] = { "/usr/sbin/iptables", "-t", "nat", "-A", "POSTROUTING", "-o", inetdev, "-j", "MASQUERADE", NULL };
-       const char *dnsmasq[] = { "/sbin/start-stop-daemon", "-S", "-p", runfile, "-b", "-x", "/usr/sbin/dnsmasq", "--", "-x", runfile, "-k", "-I", "lo", "-i", device->name, "-a", device->address, "-z", "-F", range, NULL };
-       char *forwsysctl = NULL;
-       if (asprintf(&forwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", device->name) == -1) {
-               fprintf(stderr, "Can't construct sysctl path for device %s: %s\n", device->name, strerror(errno));
-               free(runfile);
-               free(range);
-               return;
-       }
-       char *inetforwsysctl = NULL;
-       if (asprintf(&inetforwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", inetdev) == -1) {
-               fprintf(stderr, "Can't construct inet sysctl path for device %s: %s\n", inetdev, strerror(errno));
-               free(runfile);
-               free(range);
-               free(forwsysctl);
-               return;
-       }
-
-
-       if (launch(ifconfig) == 0) {
-               if (launch(modprobe) == 0) {
-                       if (launch(iptables) == 0) {
-                               if (launch(dnsmasq) == 0) {
-                                       int ffd = open(forwsysctl, O_WRONLY, 0666);
-                                       if (ffd < 0) {
-                                               fprintf(stderr, "Can't enable forwarding on PAN device %s: %s\n", device->name, strerror(errno));
-                                       } else {
-                                               if (write(ffd, "1", 1) == -1) {
-                                                       fprintf(stderr, "Can't enable forwarding on PAN device %s: %s\n", device->name, strerror(errno));
-                                               } else {
-                                                       int ifd = open(inetforwsysctl, O_WRONLY, 0666);
-                                                       if (ifd < 0) {
-                                                               fprintf(stderr, "Can't enable forwarding on WAN device %s (path %s): %s\n", inetdev, inetforwsysctl, strerror(errno));
-                                                       } else {
-                                                               if (write(ifd, "1", 1) == -1) {
-                                                                       fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno));
-                                                               }
-                                                               close(ifd);
-                                                       }
-                                               }
-                                               close(ffd);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       free(range);
-       free(runfile);
-       free(forwsysctl);
-       free(inetforwsysctl);
-
-       active++;
-}
-
-static void removed(Device *device, const char *inetdev) {
-       printf("Got org.kernel.kevent.remove on %s\n", device->name);
-
-       char *runfile = NULL;
-       if (asprintf(&runfile, "/var/run/tethering.%s.pid", device->name) == -1) {
-               fprintf(stderr, "Can't construct PID file name for device %s: %s\n", device->name, strerror(errno));
-               return;
-       }
-       const char *dnsmasq[] = { "/sbin/start-stop-daemon", "-K", "-p", runfile, "-x", "/usr/sbin/dnsmasq", NULL };
-       const char *iptables[] = { "/usr/sbin/iptables", "-t", "nat", "-D", "POSTROUTING", "-o", inetdev, "-j", "MASQUERADE", NULL };
-
-       // Errors are ignored here: we just disable as much as we can.
-       launch(dnsmasq);
-       if (unlink(runfile) == -1) {
-               fprintf(stderr, "Error removing PID file for device %s: %s\n", device->name, strerror(errno));
-       }
-       launch(iptables);
-
-       free(runfile);
-
-       if (active > 0) active--;
-       if (active == 0) {
-               char *inetforwsysctl = NULL;
-               if (asprintf(&inetforwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", inetdev) == -1) {
-                       fprintf(stderr, "Can't construct inet sysctl path for device %s: %s\n", inetdev, strerror(errno));
-                       return;
-               }
-               int fd = open(inetforwsysctl, O_WRONLY, 0666);
-               if (fd < 0) {
-                       fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno));
-               } else {
-                       if (write(fd, "0", 1) == -1) {
-                               fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno));
-                       }
-                       close(fd);
-               }
-               free(inetforwsysctl);
-       }
-}
-
-int main(int argc, const char *argv[]) {
-       active = 0;
-
-       Device *devices = NULL;
-       Device *node = NULL;
-       size_t i;
-       for (i = 0; DEVICES[i]; i++) {
-               Device *device = device_new(DEVICES[i]);
-               if (device) {
-                       device_set_address(device, ADDRESSES[i]);
-                       device_set_startaddress(device, STARTADDRESSES[i]);
-                       device_set_endaddress(device, ENDADDRESSES[i]);
-                       if (device_validate(device)) {
-                               node = device_append(node, device);
-                               if (!devices) {
-                                       devices = node;
-                               }
-                       } else {
-                               device_delete(device);
-                       }
-               }
-       }
-
-       if (!devices) {
-               fprintf(stderr, "Warning, no devices configured. I will just sit here and wait for nicer weather.\n");
-       }
-
-       DBusError err;
-       dbus_error_init(&err);
-       DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-       if (dbus_error_is_set(&err)) {
-               fprintf(stderr, "Error %s occured: %s\n", err.name, err.message);
-               dbus_error_free(&err);
-       }
-       if (!conn) {
-               return 1;
-       }
-
-       for (node = devices; node; node = node->next) {
-               char *filter = NULL;
-               if (!asprintf(&filter, "type='signal',interface='org.kernel.kevent',path='/org/kernel/class/net/%s'", node->name)) {
-                       fprintf(stderr, "Can't construct filter rule for device %s: %s\n", node->name, strerror(errno));
-               } else {
-                       dbus_bus_add_match(conn, filter, NULL);
-                       free(filter);
-               }
-       }
-       dbus_connection_flush(conn);
-
-       running = 1;
-       signal(SIGINT, siginthandler);
-       while (running) {
-               dbus_connection_read_write(conn, POLL_MAINLOOP);
-               DBusMessage* msg = dbus_connection_pop_message(conn);
-               if (msg) {
-                       if (dbus_message_is_signal(msg, "org.kernel.kevent", "add")) {
-                               char **path = NULL;
-                               if (!dbus_message_get_path_decomposed(msg, &path)) {
-                                       fprintf(stderr, "Can't get add message path!\n");
-                               } else {
-                                       unsigned int last;
-                                       for (last = 0; path[last] && last <= 6; last++);
-                                       if (last == 0 || last > 6) {
-                                               fprintf(stderr, "Add message has no path or path too long!\n");
-                                       } else {
-                                               Device *device = device_search(devices, path[last - 1]);
-                                               if (device) {
-                                                       added(device, INETDEV);
-                                               }
-                                       }
-                                       dbus_free_string_array(path);
-                               }
-                       } else if (dbus_message_is_signal(msg, "org.kernel.kevent", "remove")) {
-                               char **path = NULL;
-                               if (!dbus_message_get_path_decomposed(msg, &path)) {
-                                       fprintf(stderr, "Can't get remove message path!\n");
-                               } else {
-                                       unsigned int last;
-                                       for (last = 0; path[last] && last <= 6; last++);
-                                       if (last == 0 || last > 6) {
-                                               fprintf(stderr, "Remove message has no path or path too long!\n");
-                                       } else {
-                                               Device *device = device_search(devices, path[last - 1]);
-                                               if (device) {
-                                                       removed(device, INETDEV);
-                                               }
-                                       }
-                                       dbus_free_string_array(path);
-                               }
-                       }
-                       dbus_message_unref(msg);
-               }
-       }
-
-       device_delete_all(devices);
-       dbus_connection_unref(conn);
-       return 0;
-}
diff --git a/mtetherd.c b/mtetherd.c
new file mode 100644 (file)
index 0000000..6305bc7
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+  mtetherd
+  (c) 2010 Gregor Riepl <onitake@gmail.com>
+  
+  Tethering utility for Maemo
+  
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+  
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+  
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+#include <dbus/dbus.h>
+#include "device.h"
+
+static const char *INETDEV = "gprs0";
+static const char *DEVICES[] = {
+       "usb0",
+       "bnep0",
+       NULL
+};
+static const char *ADDRESSES[] = {
+       "192.168.253.254",
+       "192.168.254.254",
+       NULL
+};
+static const char *STARTADDRESSES[] = {
+       "192.168.253.1",
+       "192.168.254.1",
+       NULL
+};
+static const char *ENDADDRESSES[] = {
+       "192.168.253.254",
+       "192.168.254.254",
+       NULL
+};
+// Wait x seconds for process termination
+static const unsigned int TERMINATE_WAIT = 5;
+// Poll the main loop after x milliseconds
+static const unsigned int POLL_MAINLOOP = 500;
+
+// Run loop active flag
+static int running;
+// Number of active tethering connections
+static unsigned int active;
+
+static void siginthandler(int sig) {
+       if (running) {
+               fprintf(stderr, "SIGINIT received, exiting\n");
+               running = 0;
+       } else {
+               fprintf(stderr, "Another SIGINIT received, aborting\n");
+               if (kill(getpid(), SIGKILL) == -1) {
+                       fprintf(stderr, "PANIC! Error killing self: %s\n", strerror(errno));
+               }
+       }
+}
+
+static int launch(const char *args[]) {
+       pid_t pid = fork();
+       if (pid == 0) {
+               if (execv(args[0], (char **const) args) == -1) {
+                       fprintf(stderr, "Error launching external process %s: %s\n", args[0], strerror(errno));
+                       exit(1);
+               }
+       } else if (pid == -1) {
+               fprintf(stderr, "Can't fork external process %s: %s\n", args[0], strerror(errno));
+               return -1;
+       } else {
+               /*printf("Launching:");
+               size_t a;
+               for (a = 0; args[a]; a++) {
+                       printf(" %s", args[a]);
+               }
+               printf("\n");*/
+               int status = 0;
+               if (waitpid(pid, &status, WNOHANG) == -1) {
+                       fprintf(stderr, "Error waiting for child process completion: %s\n", strerror(errno));
+                       return -2;
+               }
+               size_t i;
+               for (i = 0; i < TERMINATE_WAIT && !WIFEXITED(status); i++) {
+                       if (WIFEXITED(status)) {
+                               if (WEXITSTATUS(status) != 0) {
+                                       fprintf(stderr, "Child process returned error: %d\n", WEXITSTATUS(status));
+                                       return -3;
+                               }
+                       } else if (WIFSIGNALED(status)) {
+                               fprintf(stderr, "Child process killed by signal: %d\n", WTERMSIG(status));
+                               return -4;
+                       }
+                       sleep(1);
+                       if (waitpid(pid, &status, WNOHANG) == -1) {
+                               fprintf(stderr, "Error waiting for child process completion: %s\n", strerror(errno));
+                               return -2;
+                       }
+               }
+               if (i >= TERMINATE_WAIT) {
+                       fprintf(stderr, "Child process %s still running after %u seconds, ignoring.\n", args[0], TERMINATE_WAIT);
+                       return -5;
+               }
+       }
+       return 0;
+}
+
+static void added(Device *device, const char *inetdev) {
+       printf("Got org.kernel.kevent.add on %s\n", device->name);
+       char *runfile = NULL;
+       if (asprintf(&runfile, "/var/run/tethering.%s.pid", device->name) == -1) {
+               fprintf(stderr, "Can't construct PID file name for device %s: %s\n", device->name, strerror(errno));
+               return;
+       }
+       char *range = NULL;
+       if (asprintf(&range, "%s,%s,3600", device->startaddress, device->endaddress) == -1) {
+               fprintf(stderr, "Can't construct address range parameter for device %s: %s\n", device->name, strerror(errno));
+               free(runfile);
+               return;
+       }
+       const char *ifconfig[] = { "/sbin/ifconfig", device->name, device->address, "up", NULL };
+       const char *modprobe[] = { "/sbin/modprobe", "ipt_MASQUERADE", NULL };
+       const char *iptables[] = { "/usr/sbin/iptables", "-t", "nat", "-A", "POSTROUTING", "-o", inetdev, "-j", "MASQUERADE", NULL };
+       const char *dnsmasq[] = { "/sbin/start-stop-daemon", "-S", "-p", runfile, "-b", "-x", "/usr/sbin/dnsmasq", "--", "-x", runfile, "-k", "-I", "lo", "-i", device->name, "-a", device->address, "-z", "-F", range, NULL };
+       char *forwsysctl = NULL;
+       if (asprintf(&forwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", device->name) == -1) {
+               fprintf(stderr, "Can't construct sysctl path for device %s: %s\n", device->name, strerror(errno));
+               free(runfile);
+               free(range);
+               return;
+       }
+       char *inetforwsysctl = NULL;
+       if (asprintf(&inetforwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", inetdev) == -1) {
+               fprintf(stderr, "Can't construct inet sysctl path for device %s: %s\n", inetdev, strerror(errno));
+               free(runfile);
+               free(range);
+               free(forwsysctl);
+               return;
+       }
+
+
+       if (launch(ifconfig) == 0) {
+               if (launch(modprobe) == 0) {
+                       if (launch(iptables) == 0) {
+                               if (launch(dnsmasq) == 0) {
+                                       int ffd = open(forwsysctl, O_WRONLY, 0666);
+                                       if (ffd < 0) {
+                                               fprintf(stderr, "Can't enable forwarding on PAN device %s: %s\n", device->name, strerror(errno));
+                                       } else {
+                                               if (write(ffd, "1", 1) == -1) {
+                                                       fprintf(stderr, "Can't enable forwarding on PAN device %s: %s\n", device->name, strerror(errno));
+                                               } else {
+                                                       int ifd = open(inetforwsysctl, O_WRONLY, 0666);
+                                                       if (ifd < 0) {
+                                                               fprintf(stderr, "Can't enable forwarding on WAN device %s (path %s): %s\n", inetdev, inetforwsysctl, strerror(errno));
+                                                       } else {
+                                                               if (write(ifd, "1", 1) == -1) {
+                                                                       fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno));
+                                                               }
+                                                               close(ifd);
+                                                       }
+                                               }
+                                               close(ffd);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       free(range);
+       free(runfile);
+       free(forwsysctl);
+       free(inetforwsysctl);
+
+       active++;
+}
+
+static void removed(Device *device, const char *inetdev) {
+       printf("Got org.kernel.kevent.remove on %s\n", device->name);
+
+       char *runfile = NULL;
+       if (asprintf(&runfile, "/var/run/tethering.%s.pid", device->name) == -1) {
+               fprintf(stderr, "Can't construct PID file name for device %s: %s\n", device->name, strerror(errno));
+               return;
+       }
+       const char *dnsmasq[] = { "/sbin/start-stop-daemon", "-K", "-p", runfile, "-x", "/usr/sbin/dnsmasq", NULL };
+       const char *iptables[] = { "/usr/sbin/iptables", "-t", "nat", "-D", "POSTROUTING", "-o", inetdev, "-j", "MASQUERADE", NULL };
+
+       // Errors are ignored here: we just disable as much as we can.
+       launch(dnsmasq);
+       if (unlink(runfile) == -1) {
+               fprintf(stderr, "Error removing PID file for device %s: %s\n", device->name, strerror(errno));
+       }
+       launch(iptables);
+
+       free(runfile);
+
+       if (active > 0) active--;
+       if (active == 0) {
+               char *inetforwsysctl = NULL;
+               if (asprintf(&inetforwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", inetdev) == -1) {
+                       fprintf(stderr, "Can't construct inet sysctl path for device %s: %s\n", inetdev, strerror(errno));
+                       return;
+               }
+               int fd = open(inetforwsysctl, O_WRONLY, 0666);
+               if (fd < 0) {
+                       fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno));
+               } else {
+                       if (write(fd, "0", 1) == -1) {
+                               fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno));
+                       }
+                       close(fd);
+               }
+               free(inetforwsysctl);
+       }
+}
+
+int main(int argc, const char *argv[]) {
+       active = 0;
+
+       Device *devices = NULL;
+       Device *node = NULL;
+       size_t i;
+       for (i = 0; DEVICES[i]; i++) {
+               Device *device = device_new(DEVICES[i]);
+               if (device) {
+                       device_set_address(device, ADDRESSES[i]);
+                       device_set_startaddress(device, STARTADDRESSES[i]);
+                       device_set_endaddress(device, ENDADDRESSES[i]);
+                       if (device_validate(device)) {
+                               node = device_append(node, device);
+                               if (!devices) {
+                                       devices = node;
+                               }
+                       } else {
+                               device_delete(device);
+                       }
+               }
+       }
+
+       if (!devices) {
+               fprintf(stderr, "Warning, no devices configured. I will just sit here and wait for nicer weather.\n");
+       }
+
+       DBusError err;
+       dbus_error_init(&err);
+       DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+       if (dbus_error_is_set(&err)) {
+               fprintf(stderr, "Error %s occured: %s\n", err.name, err.message);
+               dbus_error_free(&err);
+       }
+       if (!conn) {
+               return 1;
+       }
+
+       for (node = devices; node; node = node->next) {
+               char *filter = NULL;
+               if (!asprintf(&filter, "type='signal',interface='org.kernel.kevent',path='/org/kernel/class/net/%s'", node->name)) {
+                       fprintf(stderr, "Can't construct filter rule for device %s: %s\n", node->name, strerror(errno));
+               } else {
+                       dbus_bus_add_match(conn, filter, NULL);
+                       free(filter);
+               }
+       }
+       dbus_connection_flush(conn);
+
+       running = 1;
+       signal(SIGINT, siginthandler);
+       while (running) {
+               dbus_connection_read_write(conn, POLL_MAINLOOP);
+               DBusMessage* msg = dbus_connection_pop_message(conn);
+               if (msg) {
+                       if (dbus_message_is_signal(msg, "org.kernel.kevent", "add")) {
+                               char **path = NULL;
+                               if (!dbus_message_get_path_decomposed(msg, &path)) {
+                                       fprintf(stderr, "Can't get add message path!\n");
+                               } else {
+                                       unsigned int last;
+                                       for (last = 0; path[last] && last <= 6; last++);
+                                       if (last == 0 || last > 6) {
+                                               fprintf(stderr, "Add message has no path or path too long!\n");
+                                       } else {
+                                               Device *device = device_search(devices, path[last - 1]);
+                                               if (device) {
+                                                       added(device, INETDEV);
+                                               }
+                                       }
+                                       dbus_free_string_array(path);
+                               }
+                       } else if (dbus_message_is_signal(msg, "org.kernel.kevent", "remove")) {
+                               char **path = NULL;
+                               if (!dbus_message_get_path_decomposed(msg, &path)) {
+                                       fprintf(stderr, "Can't get remove message path!\n");
+                               } else {
+                                       unsigned int last;
+                                       for (last = 0; path[last] && last <= 6; last++);
+                                       if (last == 0 || last > 6) {
+                                               fprintf(stderr, "Remove message has no path or path too long!\n");
+                                       } else {
+                                               Device *device = device_search(devices, path[last - 1]);
+                                               if (device) {
+                                                       removed(device, INETDEV);
+                                               }
+                                       }
+                                       dbus_free_string_array(path);
+                               }
+                       }
+                       dbus_message_unref(msg);
+               }
+       }
+
+       device_delete_all(devices);
+       dbus_connection_unref(conn);
+       return 0;
+}
index bf40abc..9e3d045 100644 (file)
@@ -47,7 +47,7 @@ if [ "$EVENT" = "DeviceAdded" ]; then
        ifconfig "$IFACE" "$IF_ADDRESS"
        /sbin/modprobe ipt_MASQUERADE
        /usr/sbin/iptables -t nat -A POSTROUTING -o $INETDEV -j MASQUERADE
-       start-stop-daemon -S -p "$RUNFILE" -m -b -x /usr/sbin/dnsmasq -- -k -I lo -i "$IFACE" -a $IF_ADDRESS -z -F $IF_RANGE,3600
+       /usr/sbin/start-stop-daemon -S -p "$RUNFILE" -b -x /usr/sbin/dnsmasq -- -x "$RUNFILE" -k -I lo -i "$IFACE" -a $IF_ADDRESS -z -F $IF_RANGE,3600
        echo 1 > /proc/sys/net/ipv4/conf/$IFACE/forwarding
        echo 1 > /proc/sys/net/ipv4/conf/$INETDEV/forwarding
 fi
@@ -60,7 +60,7 @@ if [ "$EVENT" = "DeviceRemoved" ]; then
        rm "$IFACEFILE"
        echo "$(date) Disabling tethering on device $IFACE" >> $LOG
        echo 0 > /proc/sys/net/ipv4/conf/$INETDEV/forwarding
-       start-stop-daemon -K -p "$RUNFILE" -x /usr/sbin/dnsmasq
+       /usr/sbin/start-stop-daemon -K -p "$RUNFILE" -x /usr/sbin/dnsmasq
        /usr/sbin/iptables -t nat -D POSTROUTING -o $INETDEV -j MASQUERADE
 fi