TetherController.cpp revision 18737845d3c6a60edd6f75ac441a1b3fed6d66a7
19d10b341a0ba46f108cb96e46691197d778cbc06San Mehat/*
29d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Copyright (C) 2008 The Android Open Source Project
39d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *
49d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
59d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * you may not use this file except in compliance with the License.
69d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * You may obtain a copy of the License at
79d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *
89d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
99d10b341a0ba46f108cb96e46691197d778cbc06San Mehat *
109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * Unless required by applicable law or agreed to in writing, software
119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * See the License for the specific language governing permissions and
149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * limitations under the License.
159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat */
169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <stdlib.h>
189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <errno.h>
1918737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat#include <fcntl.h>
2018737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat
219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <sys/socket.h>
229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <sys/stat.h>
2318737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat#include <sys/types.h>
2418737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat#include <sys/wait.h>
2518737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat
269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <netinet/in.h>
279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <arpa/inet.h>
289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#define LOG_TAG "TetherController"
309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <cutils/log.h>
319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include "TetherController.h"
349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
359d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController::TetherController() {
369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces = new InterfaceCollection();
379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders = new NetAddressCollection();
389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
429d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController::~TetherController() {
439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    InterfaceCollection::iterator it;
449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(*it);
479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces->clear();
499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders->clear();
519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
539d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::setIpFwdEnabled(bool enable) {
549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    LOGD("Setting IP forward enable = %d", enable);
569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY);
579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (fd < 0) {
589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("Failed to open ip_forward (%s)", strerror(errno));
599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (write(fd, (enable ? "1" : "0"), 1) != 1) {
639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("Failed to write ip_forward (%s)", strerror(errno));
649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(fd);
679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
709d10b341a0ba46f108cb96e46691197d778cbc06San Mehatbool TetherController::getIpFwdEnabled() {
719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int fd = open("/proc/sys/net/ipv4/ip_forward", O_RDONLY);
729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (fd < 0) {
749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("Failed to open ip_forward (%s)", strerror(errno));
759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return false;
769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    char enabled;
799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (read(fd, &enabled, 1) != 1) {
809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("Failed to read ip_forward (%s)", strerror(errno));
819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(fd);
859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return (enabled  == '1' ? true : false);
879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
899d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::startTethering(struct in_addr dhcpStart, struct in_addr dhcpEnd) {
909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid != 0) {
929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("Tethering already started");
939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        errno = EBUSY;
949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    LOGD("Starting tethering services");
989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    pid_t pid;
1009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int pipefd[2];
1019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (pipe(pipefd) < 0) {
1039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("pipe failed (%s)", strerror(errno));
1049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    /*
1089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * TODO: Create a monitoring thread to handle and restart
1099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * the daemon if it exits prematurely
1109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     */
1119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if ((pid = fork()) < 0) {
1129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("fork failed (%s)", strerror(errno));
1139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
1149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!pid) {
1199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (pipefd[0] != STDIN_FILENO) {
1219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
1229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                LOGE("dup2 failed (%s)", strerror(errno));
1239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return -1;
1249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            close(pipefd[0]);
1269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *start = strdup(inet_ntoa(dhcpStart));
1289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *end = strdup(inet_ntoa(dhcpEnd));
1299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *range;
1309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        asprintf(&range, "--dhcp-range=%s,%s,1h", start, end);
1329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (execl("/system/bin/dnsmasq", "/system/bin/dnsmasq", "--no-daemon", "--no-resolv",
1349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                  "--no-poll", "--no-hosts", range, (char *) NULL)) {
1359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            LOGE("execl failed (%s)", strerror(errno));
1369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("Should never get here!");
1389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
1399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
1409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
1419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonPid = pid;
1429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonFd = pipefd[1];
1439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGD("Tethering services running");
1449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
1479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1499d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::stopTethering() {
1509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid == 0) {
1529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGE("Tethering already stopped");
1539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
1549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    LOGD("Stopping tethering services");
1579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    kill(mDaemonPid, SIGTERM);
15918737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat    waitpid(mDaemonPid, NULL, 0);
1609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
1619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(mDaemonFd);
1629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
16318737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat    LOGD("Tethering services stopped");
1649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
1659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1679d10b341a0ba46f108cb96e46691197d778cbc06San Mehatbool TetherController::isTetheringStarted() {
1689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return (mDaemonPid == 0 ? false : true);
1699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1719d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::setDnsForwarders(char **servers, int numServers) {
1729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int i;
1739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    char daemonCmd[1024];
1749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    strcpy(daemonCmd, "update_dns");
1769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders->clear();
1789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (i = 0; i < numServers; i++) {
1799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGD("setDnsForwarders(%d = '%s')", i, servers[i]);
1809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        struct in_addr a;
1829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!inet_aton(servers[i], &a)) {
1849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            LOGE("Failed to parse DNS server '%s'", servers[i]);
1859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mDnsForwarders->clear();
1869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
1879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        strcat(daemonCmd, ":");
1899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        strcat(daemonCmd, servers[i]);
1909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDnsForwarders->push_back(a);
1919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonFd != -1) {
1949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        LOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
1959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
1969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            LOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
1979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mDnsForwarders->clear();
1989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
1999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
2009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
2029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2049d10b341a0ba46f108cb96e46691197d778cbc06San MehatNetAddressCollection *TetherController::getDnsForwarders() {
2059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mDnsForwarders;
2069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2089d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::tetherInterface(const char *interface) {
2099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces->push_back(strdup(interface));
2109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
2119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2139d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::untetherInterface(const char *interface) {
2149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    InterfaceCollection::iterator it;
2159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
2179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!strcmp(interface, *it)) {
2189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            free(*it);
2199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mInterfaces->erase(it);
2209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
2219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
2229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    errno = ENOENT;
2249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return -1;
2259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2279d10b341a0ba46f108cb96e46691197d778cbc06San MehatInterfaceCollection *TetherController::getTetheredInterfaceList() {
2289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mInterfaces;
2299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
231