From: Gregor Riepl Date: Tue, 20 Jul 2010 23:44:09 +0000 (+0200) Subject: Added more error checking, cleaned up the code X-Git-Tag: v0.1~9 X-Git-Url: http://vcs.maemo.org/git/?p=mtetherd;a=commitdiff_plain;h=f6236fca743c1bc9357e7e130fe5a799b9968e79 Added more error checking, cleaned up the code Prepared code for configuration file feature --- diff --git a/main.c b/main.c index b3bb6c4..e659c84 100644 --- a/main.c +++ b/main.c @@ -8,8 +8,8 @@ #include #include #include +#include #include -//#include static const char *INETDEV = "gprs0"; static const char *DEVICES[] = { @@ -36,37 +36,11 @@ static const char *ENDADDRESSES[] = { static int running; static unsigned int active; -static void sigIntHandler(int sig) { +static void siginthandler(int sig) { fprintf(stderr, "SIGINIT received, exiting\n"); running = 0; } -/*static void deviceAdded(LibHalContext *ctx, const char *udi) { - DBusError err; - dbus_error_init(&err); - char *device = libhal_device_get_property_string(ctx, udi, "net.interface", &err); - if (!device) { - if (dbus_error_is_set(&err)) { - fprintf(stderr, "Error %s occured: %s\n", err.name, err.message); - dbus_error_free(&err); - } - } - printf("Device %s added.\n", device); -} - -static void deviceRemoved(LibHalContext *ctx, const char *udi) { - DBusError err; - dbus_error_init(&err); - char *device = libhal_device_get_property_string(ctx, udi, "net.interface", &err); - if (!device) { - if (dbus_error_is_set(&err)) { - fprintf(stderr, "Error %s occured: %s\n", err.name, err.message); - dbus_error_free(&err); - } - } - printf("Device %s removed.\n", device); -}*/ - static int launch(const char *args[]) { pid_t pid = fork(); if (pid == 0) { @@ -96,77 +70,131 @@ static int launch(const char *args[]) { return 0; } -static void added(const char *device, const char *inetdev, const char *address, const char *startaddress, const char *endaddress) { +static void added(const char *device, const char *inetdev, struct in_addr address, struct in_addr startaddress, struct in_addr endaddress) { printf("Got org.kernel.kevent.add on %s\n", device); - const char *ifconfig[] = { "/sbin/ifconfig", device, address, "up", NULL }; - launch(ifconfig); - const char *modprobe[] = { "/sbin/modprobe", "ipt_MASQUERADE", NULL }; - launch(modprobe); - const char *iptables[] = { "/usr/sbin/iptables", "-t", "nat", "-A", "POSTROUTING", "-o", inetdev, "-j", "MASQUERADE", NULL }; - launch(iptables); + char ascaddress[16]; + if (inet_ntop(AF_INET, &address, ascaddress, sizeof(ascaddress)) == NULL) { + fprintf(stderr, "Can't convert address for device %s\n", device); + return; + } + char ascstartaddress[16]; + if (inet_ntop(AF_INET, &startaddress, ascstartaddress, sizeof(ascstartaddress)) == NULL) { + fprintf(stderr, "Can't convert start address for device %s\n", device); + return; + } + char ascendaddress[16]; + if (inet_ntop(AF_INET, &endaddress, ascendaddress, sizeof(ascendaddress)) == NULL) { + fprintf(stderr, "Can't convert end address for device %s\n", device); + return; + } char *runfile = NULL; - asprintf(&runfile, "/var/run/tethering.%s.pid", device); + if (asprintf(&runfile, "/var/run/tethering.%s.pid", device) == -1) { + fprintf(stderr, "Can't construct PID file name for device %s: %s\n", device, strerror(errno)); + return; + } char *range = NULL; - asprintf(&range, "%s-%s,3600", startaddress, endaddress); - const char *dnsmasq[] = { "/sbin/start-stop-daemon", "-S", "-p", runfile, "-m", "-b", "-x", "/usr/sbin/dnsmasq", "--", "-k", "-I", "lo", "-i", device, "-a", address, "-z", "-F", range, NULL }; - launch(dnsmasq); - free(range); - free(runfile); + if (asprintf(&range, "%s-%s,3600", ascstartaddress, ascendaddress) == -1) { + fprintf(stderr, "Can't construct address range parameter for device %s: %s\n", device, strerror(errno)); + free(runfile); + return; + } + const char *ifconfig[] = { "/sbin/ifconfig", device, ascaddress, "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, "-a", ascaddress, "-z", "-F", range, NULL }; char *forwsysctl = NULL; - asprintf(&forwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", device); - int fd = open(forwsysctl, O_WRONLY, 0666); - if (fd < 0) { - perror("Can't enable forwarding on PAN device"); - } else { - if (write(fd, "0", 1) == -1) { - perror("Can't enable forwarding on PAN device"); - } - close(fd); + if (asprintf(&forwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", device) == -1) { + fprintf(stderr, "Can't construct sysctl path for device %s: %s\n", device, strerror(errno)); + free(runfile); + free(range); + return; } - free(forwsysctl); - asprintf(&forwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", inetdev); - fd = open(forwsysctl, O_WRONLY, 0666); - if (fd < 0) { - perror("Can't enable forwarding on WAN device"); - } else { - if (write(fd, "0", 1) == -1) { - perror("Can't enable forwarding on WAN device"); + 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", device, 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, strerror(errno)); + } else { + if (write(ffd, "1", 1) == -1) { + fprintf(stderr, "Can't enable forwarding on PAN device %s: %s\n", device, strerror(errno)); + } else { + int ifd = open(inetforwsysctl, O_WRONLY, 0666); + if (ifd < 0) { + fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, 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); + } + } + } } - close(fd); } + + free(range); + free(runfile); free(forwsysctl); + free(inetforwsysctl); + active++; } static void removed(const char *device, const char *inetdev) { printf("Got org.kernel.kevent.remove on %s\n", device); + char *runfile = NULL; - asprintf(&runfile, "/var/run/tethering.%s.pid", device); + if (asprintf(&runfile, "/var/run/tethering.%s.pid", device) == -1) { + fprintf(stderr, "Can't construct PID file name for device %s: %s\n", device, strerror(errno)); + return; + } const char *dnsmasq[] = { "/sbin/start-stop-daemon", "-K", "-p", runfile, "-x", "/usr/sbin/dnsmasq", NULL }; - launch(dnsmasq); - free(runfile); 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); launch(iptables); + + free(runfile); + if (active > 0) active--; if (active == 0) { - char *forwsysctl = NULL; - asprintf(&forwsysctl, "/proc/sys/net/ipv4/conf/%s/forwarding", inetdev); - int fd = open(forwsysctl, O_WRONLY, 0666); + 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", device, strerror(errno)); + return; + } + int fd = open(inetforwsysctl, O_WRONLY, 0666); if (fd < 0) { - perror("Can't disable forwarding on WAN device"); + fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno)); } else { if (write(fd, "0", 1) == -1) { - perror("Can't disable forwarding on WAN device"); + fprintf(stderr, "Can't enable forwarding on WAN device %s: %s\n", inetdev, strerror(errno)); } close(fd); } - free(forwsysctl); + free(inetforwsysctl); } } -static int finddev(const char* device, const char *devices[]) { +static int finddev(const char* device, const char *devices[], size_t size) { int i; - for (i = 0; devices[i]; i++) { + for (i = 0; i < size; i++) { if (strcmp(device, devices[i]) == 0) { return i; } @@ -177,7 +205,44 @@ static int finddev(const char* device, const char *devices[]) { int main(int argc, const char *argv[]) { running = 1; active = 0; - signal(SIGINT, sigIntHandler); + signal(SIGINT, siginthandler); + + size_t sizedevices = sizeof(DEVICES) / sizeof(DEVICES[0]); + const char *devices[sizedevices]; + struct in_addr addresses[sizedevices]; + struct in_addr startaddresses[sizedevices]; + struct in_addr endaddresses[sizedevices]; + size_t numdevices = 0; + size_t i; + for (i = 0; i < sizedevices; i++) { + int err = inet_pton(AF_INET, ADDRESSES[i], &addresses[numdevices]); + if (err == 0) { + fprintf(stderr, "Invalid address for device %s: %s\n", DEVICES[i], ADDRESSES[i]); + } else if (err == -1) { + fprintf(stderr, "Error converting address for device %s: %s\n", DEVICES[i], ADDRESSES[i]); + } else { + int err = inet_pton(AF_INET, STARTADDRESSES[i], &startaddresses[numdevices]); + if (err == 0) { + fprintf(stderr, "Invalid DHCP start address for device %s: %s\n", DEVICES[i], STARTADDRESSES[i]); + } else if (err == -1) { + fprintf(stderr, "Error converting DHCP start address for device %s: %s\n", DEVICES[i], STARTADDRESSES[i]); + } else { + int err = inet_pton(AF_INET, ENDADDRESSES[i], &endaddresses[numdevices]); + if (err == 0) { + fprintf(stderr, "Invalid DHCP end address for device %s: %s\n", DEVICES[i], ENDADDRESSES[i]); + } else if (err == -1) { + fprintf(stderr, "Error converting DHCP end address for device %s: %s\n", DEVICES[i], ENDADDRESSES[i]); + } else { + devices[numdevices] = DEVICES[i]; + numdevices++; + } + } + } + } + + if (numdevices == 0) { + fprintf(stderr, "Warning, no devices configured. I will just sit here and wait for nicer weather.\n"); + } DBusError err; dbus_error_init(&err); @@ -189,75 +254,21 @@ int main(int argc, const char *argv[]) { if (!conn) { return 1; } - /*LibHalContext *ctx = libhal_ctx_new(); - if (!ctx) { - fprintf(stderr, "Error occured: Can't create HAL context.\n"); - return 2; - } - if (!libhal_ctx_set_dbus_connection(ctx, conn)) { - fprintf(stderr, "Error occured: Can't assign DBUS connection to HAL context.\n"); - return 3; - } - if (!libhal_ctx_set_device_added(ctx, deviceAdded)) { - fprintf(stderr, "Error occured: Can't set device added message handler.\n"); - return 4; - } - if (!libhal_ctx_set_device_removed(ctx, deviceRemoved)) { - fprintf(stderr, "Error occured: Can't set device removed message handler.\n"); - return 4; - } - if (!libhal_ctx_init(ctx, &err)) { - if (dbus_error_is_set(&err)) { - fprintf(stderr, "Error %s occured: %s\n", err.name, err.message); - dbus_error_free(&err); - } - return 5; - } - dbus_bool_t nodisc = TRUE; - while (running && nodisc) { - nodisc = dbus_connection_read_write_dispatch(conn, 500); - }*/ - //dbus_bus_add_match(conn, "type='signal',interface='org.freedesktop.Hal.Manager',member='DeviceAdded'", NULL); - //dbus_bus_add_match(conn, "type='signal',interface='org.freedesktop.Hal.Manager',member='DeviceRemoved'", NULL); - //dbus_bus_add_match(conn, "type='signal',interface='org.kernel.kevent',path='/org/kernel/class/net/bnep0'", NULL); - //dbus_bus_add_match(conn, "type='signal',interface='org.kernel.kevent',path='/org/kernel/class/net/usb0'", NULL); - int i; - for (i = 0; DEVICES[i]; i++) { + + for (i = 0; i < numdevices; i++) { char *filter = NULL; - if (!asprintf(&filter, "type='signal',interface='org.kernel.kevent',path='/org/kernel/class/net/%s'", DEVICES[i])) { - perror("Can't construct filter rule"); + if (!asprintf(&filter, "type='signal',interface='org.kernel.kevent',path='/org/kernel/class/net/%s'", devices[i])) { + fprintf(stderr, "Can't construct filter rule for device %s: %s\n", devices[i], strerror(errno)); } else { dbus_bus_add_match(conn, filter, NULL); } } dbus_connection_flush(conn); + while (running) { dbus_connection_read_write(conn, 500); DBusMessage* msg = dbus_connection_pop_message(conn); if (msg) { - /*if (dbus_message_is_signal(msg, "org.freedesktop.Hal.Manager", "DeviceAdded")) { - DBusMessageIter args; - if (!dbus_message_iter_init(msg, &args)) { - fprintf(stderr, "Message has no arguments!\n"); - } else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { - fprintf(stderr, "Argument is not a string!\n"); - } else { - char *sigvalue = NULL; - dbus_message_iter_get_basic(&args, &sigvalue); - fprintf(stderr, "Got DeviceAdded with value %s\n", sigvalue); - } - } else if (dbus_message_is_signal(msg, "org.freedesktop.Hal.Manager", "DeviceRemoved")) { - DBusMessageIter args; - if (!dbus_message_iter_init(msg, &args)) { - fprintf(stderr, "Message has no arguments!\n"); - } else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { - fprintf(stderr, "Argument is not a string!\n"); - } else { - char *sigvalue = NULL; - dbus_message_iter_get_basic(&args, &sigvalue); - fprintf(stderr, "Got DeviceRemoved with value %s\n", sigvalue); - } - } else */ if (dbus_message_is_signal(msg, "org.kernel.kevent", "add")) { char **path = NULL; if (!dbus_message_get_path_decomposed(msg, &path)) { @@ -268,10 +279,10 @@ int main(int argc, const char *argv[]) { if (last == 0 || last > 6) { fprintf(stderr, "Add message has no path or path too long!\n"); } else { - int index = finddev(path[last - 1], DEVICES); + int index = finddev(path[last - 1], devices, numdevices); if (index >= 0) { - added(DEVICES[index], INETDEV, ADDRESSES[index], STARTADDRESSES[index], ENDADDRESSES[index]); + added(devices[index], INETDEV, addresses[index], startaddresses[index], endaddresses[index]); } } dbus_free_string_array(path); @@ -286,9 +297,9 @@ int main(int argc, const char *argv[]) { if (last == 0 || last > 6) { fprintf(stderr, "Remove message has no path or path too long!\n"); } else { - int index = finddev(path[last - 1], DEVICES); + int index = finddev(path[last - 1], devices, numdevices); if (index >= 0) { - removed(DEVICES[index], INETDEV); + removed(devices[index], INETDEV); } } dbus_free_string_array(path); @@ -297,13 +308,7 @@ int main(int argc, const char *argv[]) { dbus_message_unref(msg); } } - /*if (!libhal_ctx_shutdown(ctx, &err)) { - if (dbus_error_is_set(&err)) { - fprintf(stderr, "Error %s occured: %s\n", err.name, err.message); - dbus_error_free(&err); - } - } - libhal_ctx_free(ctx);*/ + dbus_connection_unref(conn); return 0; }