From: Gregor Riepl Date: Thu, 22 Jul 2010 16:07:22 +0000 (+0200) Subject: Added upstart script X-Git-Tag: v0.1~5 X-Git-Url: https://vcs.maemo.org/git/?a=commitdiff_plain;h=7fd4efd5c62907c58e81af8df73a65875f7248ed;hp=62befab10c1a61d24d2e511758472dc05e6c8525;p=mtetherd Added upstart script Modified readme with new project name and copyright Fixed bugs, the daemon is tested and working for Bluetooth at least Added network device name validation --- diff --git a/README b/README index 613db3f..ada9d53 100644 --- a/README +++ b/README @@ -1,20 +1,25 @@ -maemo-tethering 1.0 -------------------- +mtetherd 0.1 +------------ Description: -maemo-tethering allows you to use your N900 as an Internet router. +mtetherd allows you to use your N900 as an Internet router. Once a USB network or Bluetooth PAN connection is opened to the device, it will automatically configure networking and start a dnsmasq instance that serves DHCP requests and forwards DNS queries. -This tool can also be used to automatically configure network interfaces +You can also use it to automatically configure network interfaces for development. +Requirements: + +The iptables and bluetooth-dun packages must be installed. +They are required for setting up NAT and Bluetooth PAN support. + Usage: Bluetooth: 1. Pair your host with the N900 and make sure the PAN (Bluetooth networking) - service is recognized. + service is recognized on the host. 2. Open a PAN connection to the N900. 3. Routing should setup automatically and you can access the Internet right away. @@ -28,7 +33,7 @@ USB: 6. The USB mode is kept between cable disconnects, you only have to reload the g_ether module after a reboot or mode change. 7. Start surfing on the host. -3a.It is also possible to load the module from the Terminal: +3a.It is also possible to load the module from the Terminal (untested): rmmod g_nokia rmmod g_file_storage modprobe g_ether @@ -36,7 +41,7 @@ modprobe g_ether Notes: IP addresses are currently hardcoded into the program. A later version -will add support for a configuration file. +will add support for an external configuration file. The assigned addresses are the following: USB: N900: 192.168.253.254 DHCP: 192.168.253.1-192.168.253.253 Bluetooth: N900: 192.168.254.254 DHCP: 192.168.254.1-192.168.254.253 @@ -48,8 +53,15 @@ You can still communicate with the device, but not surf the internet from your host. Just disconnect and reconnect again when the GPRS/UMTS connection is available. +Bugs: + +Likely. +Please submit a bug report on garage.maemo.org if you find any! + Legal: +mtetherd is (c) 2010 by Gregor Riepl + 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 diff --git a/device.c b/device.c index 9dbe424..7902ee4 100644 --- a/device.c +++ b/device.c @@ -1,21 +1,21 @@ /* -maemo-tethering -(c) 2010 Gregor Riepl - -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 . + maemo-tethering + (c) 2010 Gregor Riepl + + 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 . */ #include @@ -35,14 +35,11 @@ Device *device_new(const char *name) { return NULL; } memset(ret, 0, sizeof(Device)); - size_t length = strlen(name) + 1; - ret->name = malloc(length); + device_set_name(ret, name); if (!ret->name) { - fprintf(stderr, "Error allocating memory for device name.\n"); free(ret); return NULL; } - memcpy(ret->name, name, length); return ret; } @@ -92,10 +89,31 @@ Device *device_set_name(Device *device, const char *name) { return NULL; } free(device->name); - size_t length = strlen(name) + 1; - device->name = malloc(length); + size_t length = strlen(name); + device->name = malloc(length + 1); if (!device->name) { fprintf(stderr, "Error allocating memory for device name.\n"); + } else { + int filtered = 0; + size_t i, j; + for (i = 0, j = 0; i < length; i++) { + if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= '0' && name[i] <= '9')) { + device->name[j] = name[i]; + j++; + } else { + filtered = 1; + } + } + device->name[j] = '\0'; + if (j == 0) { + fprintf(stderr, "Error: Invalid device name.\n"); + free(device->name); + device->name = NULL; + } else { + if (filtered) { + fprintf(stderr, "Warning, device name contained invalid characters. They have been removed.\n"); + } + } } return device; } @@ -192,7 +210,7 @@ int device_validate(Device *device) { } Device *device_search(Device *start, const char *name) { - while (start) { + for (; start; start = start->next) { if (strcmp(start->name, name) == 0) { return start; } diff --git a/device.h b/device.h index 66e0002..3a216f0 100644 --- a/device.h +++ b/device.h @@ -1,21 +1,21 @@ /* -maemo-tethering -(c) 2010 Gregor Riepl - -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 . + maemo-tethering + (c) 2010 Gregor Riepl + + 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 . */ struct Device; diff --git a/event.d-maemo-tethering b/event.d-maemo-tethering new file mode 100644 index 0000000..cf4dd9d --- /dev/null +++ b/event.d-maemo-tethering @@ -0,0 +1,12 @@ +description "maemo-tethering" +author "Gregor Riepl " + +start on started dbus +stop on stopping dbus + +console none + +exec /usr/sbin/maemo-tethering + +respawn + diff --git a/main.c b/main.c index ac3f25b..d86ad4e 100644 --- a/main.c +++ b/main.c @@ -1,21 +1,21 @@ /* -maemo-tethering -(c) 2010 Gregor Riepl - -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 . + maemo-tethering + (c) 2010 Gregor Riepl + + 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 . */ #include @@ -33,8 +33,8 @@ along with this program. If not, see . static const char *INETDEV = "gprs0"; static const char *DEVICES[] = { - "bnep0", "usb0", + "bnep0", NULL }; static const char *ADDRESSES[] = { @@ -52,6 +52,10 @@ static const char *ENDADDRESSES[] = { "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; @@ -59,8 +63,15 @@ static int running; static unsigned int active; static void siginthandler(int sig) { - fprintf(stderr, "SIGINIT received, exiting\n"); - running = 0; + 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[]) { @@ -74,19 +85,37 @@ static int launch(const char *args[]) { 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, 0) == -1) { - perror("Error waiting for child process completion"); - return -1; + if (waitpid(pid, &status, WNOHANG) == -1) { + fprintf(stderr, "Error waiting for child process completion: %s\n", strerror(errno)); + return -2; } - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) != 0) { - fprintf(stderr, "Child process returned error: %d\n", WEXITSTATUS(status)); - return -1; + 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; } - } else if (WIFSIGNALED(status)) { - fprintf(stderr, "Child process killed by signal: %d\n", WTERMSIG(status)); - return -1; + } + if (i >= TERMINATE_WAIT) { + fprintf(stderr, "Child process %s still running after %u seconds, ignoring.\n", args[0], TERMINATE_WAIT); + return -5; } } return 0; @@ -100,7 +129,7 @@ static void added(Device *device, const char *inetdev) { return; } char *range = NULL; - if (asprintf(&range, "%s-%s,3600", device->startaddress, device->endaddress) == -1) { + 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; @@ -108,7 +137,7 @@ static void added(Device *device, const char *inetdev) { 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, "-m", "-b", "-x", "/usr/sbin/dnsmasq", "--", "-k", "-I", "lo", "-i", device->name, "-a", device->address, "-z", "-F", range, 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)); @@ -175,6 +204,9 @@ static void removed(Device *device, const char *inetdev) { // 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); @@ -200,9 +232,7 @@ static void removed(Device *device, const char *inetdev) { } int main(int argc, const char *argv[]) { - running = 1; active = 0; - signal(SIGINT, siginthandler); Device *devices = NULL; Device *node = NULL; @@ -250,8 +280,10 @@ int main(int argc, const char *argv[]) { } dbus_connection_flush(conn); + running = 1; + signal(SIGINT, siginthandler); while (running) { - dbus_connection_read_write(conn, 500); + 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")) {