TetherController.cpp revision 9caaa44f635f86200e2b9b4cd36d1471ce910a6a
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>
20ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h>
2118737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat
229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <sys/socket.h>
239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <sys/stat.h>
2418737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat#include <sys/types.h>
2518737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat#include <sys/wait.h>
2618737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat
279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <netinet/in.h>
289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <arpa/inet.h>
299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#define LOG_TAG "TetherController"
319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <cutils/log.h>
326b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo#include <cutils/properties.h>
339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include "TetherController.h"
359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
369d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController::TetherController() {
379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces = new InterfaceCollection();
389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders = new NetAddressCollection();
399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
419589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    mDhcpcdPid = 0;
429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
449d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController::~TetherController() {
459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    InterfaceCollection::iterator it;
469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(*it);
499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces->clear();
519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders->clear();
539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
559d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::setIpFwdEnabled(bool enable) {
569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
577b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Setting IP forward enable = %d", enable);
586b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo
596b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    // In BP tools mode, do not disable IP forwarding
606b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    char bootmode[PROPERTY_VALUE_MAX] = {0};
616b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    property_get("ro.bootmode", bootmode, "unknown");
626b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    if ((enable == false) && (0 == strcmp("bp-tools", bootmode))) {
636b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo        return 0;
646b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    }
656b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo
669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY);
679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (fd < 0) {
685ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to open ip_forward (%s)", strerror(errno));
699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (write(fd, (enable ? "1" : "0"), 1) != 1) {
735ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to write ip_forward (%s)", strerror(errno));
7437dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt        close(fd);
759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(fd);
789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
819d10b341a0ba46f108cb96e46691197d778cbc06San Mehatbool TetherController::getIpFwdEnabled() {
829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int fd = open("/proc/sys/net/ipv4/ip_forward", O_RDONLY);
839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (fd < 0) {
855ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to open ip_forward (%s)", strerror(errno));
869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return false;
879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    char enabled;
909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (read(fd, &enabled, 1) != 1) {
915ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to read ip_forward (%s)", strerror(errno));
9237dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt        close(fd);
939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(fd);
979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return (enabled  == '1' ? true : false);
989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1003208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwaltint TetherController::startTethering(int num_addrs, struct in_addr* addrs) {
1019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid != 0) {
1025ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Tethering already started");
1039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        errno = EBUSY;
1049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1077b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Starting tethering services");
1089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    pid_t pid;
1109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int pipefd[2];
1119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (pipe(pipefd) < 0) {
1135ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("pipe failed (%s)", strerror(errno));
1149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    /*
1189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * TODO: Create a monitoring thread to handle and restart
1199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * the daemon if it exits prematurely
1209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     */
1219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if ((pid = fork()) < 0) {
1225ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("fork failed (%s)", strerror(errno));
1239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
1249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!pid) {
1299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (pipefd[0] != STDIN_FILENO) {
1319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
1325ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block                ALOGE("dup2 failed (%s)", strerror(errno));
1339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return -1;
1349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            close(pipefd[0]);
1369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1389997f9a3edac2baac244c2fe8e49685a3be9f482Jean-Baptiste Queru        int num_processed_args = 7 + (num_addrs/2) + 1; // 1 null for termination
1393208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        char **args = (char **)malloc(sizeof(char *) * num_processed_args);
1403208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[num_processed_args - 1] = NULL;
1413208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[0] = (char *)"/system/bin/dnsmasq";
142b756f69226d86380ea88b9330356c9fd210dbafePeter Nilsson        args[1] = (char *)"--keep-in-foreground";
1433208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[2] = (char *)"--no-resolv";
1443208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[3] = (char *)"--no-poll";
1456df79da87b57437505eedd7fdf5359f9e67c38ddJeff Sharkey        // TODO: pipe through metered status from ConnService
1466df79da87b57437505eedd7fdf5359f9e67c38ddJeff Sharkey        args[4] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
1479997f9a3edac2baac244c2fe8e49685a3be9f482Jean-Baptiste Queru        args[5] = (char *)"--pid-file";
1489997f9a3edac2baac244c2fe8e49685a3be9f482Jean-Baptiste Queru        args[6] = (char *)"";
1493208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt
1509997f9a3edac2baac244c2fe8e49685a3be9f482Jean-Baptiste Queru        int nextArg = 7;
1513208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        for (int addrIndex=0; addrIndex < num_addrs;) {
1523208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            char *start = strdup(inet_ntoa(addrs[addrIndex++]));
1533208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            char *end = strdup(inet_ntoa(addrs[addrIndex++]));
1543208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h", start, end);
1553208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        }
1569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1573208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        if (execv(args[0], args)) {
1585ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("execl failed (%s)", strerror(errno));
1599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1605ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Should never get here!");
1613208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        free(args);
1629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
1639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
1649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
1659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonPid = pid;
1669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonFd = pipefd[1];
1677b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Tethering services running");
1689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
1719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1739d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::stopTethering() {
1749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid == 0) {
1765ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Tethering already stopped");
1779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
1789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1807b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Stopping tethering services");
1819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    kill(mDaemonPid, SIGTERM);
18318737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat    waitpid(mDaemonPid, NULL, 0);
1849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
1859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(mDaemonFd);
1869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
1877b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Tethering services stopped");
1889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
1899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1909589a4c6e0b6a5ec60c65b248e7deff2805749b2zzyint TetherController::startReverseTethering(const char* iface) {
1919589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    if (mDhcpcdPid != 0) {
1929caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie        ALOGE("Reverse tethering already started");
1939589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        errno = EBUSY;
1949589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        return -1;
1959589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    }
1969589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy
1979caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie    ALOGD("TetherController::startReverseTethering, Starting reverse tethering");
1989589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy
1999589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    /*
2009589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy     * TODO: Create a monitoring thread to handle and restart
2019589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy     * the daemon if it exits prematurely
2029589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy     */
2039589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    //cleanup the dhcp result
2049589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    char dhcp_result_name[64];
2059589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    snprintf(dhcp_result_name, sizeof(dhcp_result_name) - 1, "dhcp.%s.result", iface);
2069589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    property_set(dhcp_result_name, "");
2079589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy
2089589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    pid_t pid;
2099589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    if ((pid = fork()) < 0) {
2109caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie        ALOGE("fork failed (%s)", strerror(errno));
2119589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        return -1;
2129589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    }
2139589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy
2149589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    if (!pid) {
2159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2169589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        char *args[10];
2179589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        int argc = 0;
2189589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        args[argc++] = "/system/bin/dhcpcd";
2199589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        char host_name[128];
2209589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        if (property_get("net.hostname", host_name, NULL) && (host_name[0] != '\0'))
2219589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        {
2229589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy            args[argc++] = "-h";
2239589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy            args[argc++] = host_name;
2249589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        }
2259589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        args[argc++] = (char*)iface;
2269589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        args[argc] = NULL;
2279589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        if (execv(args[0], args)) {
2289caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie            ALOGE("startReverseTethering, execv failed (%s)", strerror(errno));
2299589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        }
2309caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie        ALOGE("startReverseTethering, Should never get here!");
2319589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        return 0;
2329589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    } else {
2339589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        mDhcpcdPid = pid;
2349caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie        ALOGD("Reverse Tethering running, pid:%d", pid);
2359589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    }
2369589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    return 0;
2379589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy}
2389589a4c6e0b6a5ec60c65b248e7deff2805749b2zzyint TetherController::stopReverseTethering() {
2399589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy
2409589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    if (mDhcpcdPid == 0) {
2419caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie        ALOGE("Tethering already stopped");
2429589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy        return 0;
2439589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    }
2449589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy
2459caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie    ALOGD("Stopping tethering services");
2469589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy
2479589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    kill(mDhcpcdPid, SIGTERM);
2489589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    waitpid(mDhcpcdPid, NULL, 0);
2499589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    mDhcpcdPid = 0;
2509caaa44f635f86200e2b9b4cd36d1471ce910a6aMatthew Xie    ALOGD("Tethering services stopped");
2519589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy    return 0;
2529589a4c6e0b6a5ec60c65b248e7deff2805749b2zzy}
2539d10b341a0ba46f108cb96e46691197d778cbc06San Mehatbool TetherController::isTetheringStarted() {
2549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return (mDaemonPid == 0 ? false : true);
2559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
257cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root#define MAX_CMD_SIZE 1024
258cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
2599d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::setDnsForwarders(char **servers, int numServers) {
2609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int i;
261cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root    char daemonCmd[MAX_CMD_SIZE];
2629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    strcpy(daemonCmd, "update_dns");
264cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root    int cmdLen = strlen(daemonCmd);
2659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders->clear();
2679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (i = 0; i < numServers; i++) {
2687b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("setDnsForwarders(%d = '%s')", i, servers[i]);
2699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        struct in_addr a;
2719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!inet_aton(servers[i], &a)) {
2735ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("Failed to parse DNS server '%s'", servers[i]);
2749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mDnsForwarders->clear();
2759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
2769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
277cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
278cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root        cmdLen += strlen(servers[i]);
279cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root        if (cmdLen + 2 >= MAX_CMD_SIZE) {
2807b984e3f7e724f8a3547a707210319f3d479f261Steve Block            ALOGD("Too many DNS servers listed");
281cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root            break;
282cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root        }
283cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
2849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        strcat(daemonCmd, ":");
2859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        strcat(daemonCmd, servers[i]);
2869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDnsForwarders->push_back(a);
2879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonFd != -1) {
2907b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
2919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
2925ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
2939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mDnsForwarders->clear();
2949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
2959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
2969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
2989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3009d10b341a0ba46f108cb96e46691197d778cbc06San MehatNetAddressCollection *TetherController::getDnsForwarders() {
3019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mDnsForwarders;
3029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3049d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::tetherInterface(const char *interface) {
3059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces->push_back(strdup(interface));
3069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
3079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3099d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::untetherInterface(const char *interface) {
3109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    InterfaceCollection::iterator it;
3119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
3139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!strcmp(interface, *it)) {
3149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            free(*it);
3159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mInterfaces->erase(it);
3169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
3179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
3189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
3199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    errno = ENOENT;
3209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return -1;
3219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3239d10b341a0ba46f108cb96e46691197d778cbc06San MehatInterfaceCollection *TetherController::getTetheredInterfaceList() {
3249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mInterfaces;
3259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
326