-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.
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
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
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 <onitake@gmail.com>
+
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
/*
-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/>.
+ 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>
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;
}
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;
}
}
Device *device_search(Device *start, const char *name) {
- while (start) {
+ for (; start; start = start->next) {
if (strcmp(start->name, name) == 0) {
return start;
}
/*
-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/>.
+ 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/>.
*/
struct Device;
/*
-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/>.
+ 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>
static const char *INETDEV = "gprs0";
static const char *DEVICES[] = {
- "bnep0",
"usb0",
+ "bnep0",
NULL
};
static const char *ADDRESSES[] = {
"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;
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[]) {
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;
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;
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));
// 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);
}
int main(int argc, const char *argv[]) {
- running = 1;
active = 0;
- signal(SIGINT, siginthandler);
Device *devices = NULL;
Device *node = NULL;
}
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")) {