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
34667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti#include "Fwmark.h"
3569261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall#include "NetdConstants.h"
36667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti#include "Permission.h"
379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include "TetherController.h"
389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3987475a1471373b72ffc9f81f17dfd7884723fa86Sreeram RamachandranTetherController::TetherController() {
409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces = new InterfaceCollection();
41667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    mDnsNetId = 0;
429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders = new NetAddressCollection();
439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
479d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController::~TetherController() {
489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    InterfaceCollection::iterator it;
499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(*it);
529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces->clear();
549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders->clear();
569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
589d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::setIpFwdEnabled(bool enable) {
599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
607b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Setting IP forward enable = %d", enable);
616b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo
626b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    // In BP tools mode, do not disable IP forwarding
636b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    char bootmode[PROPERTY_VALUE_MAX] = {0};
646b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    property_get("ro.bootmode", bootmode, "unknown");
656b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    if ((enable == false) && (0 == strcmp("bp-tools", bootmode))) {
666b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo        return 0;
676b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo    }
686b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo
699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY);
709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (fd < 0) {
715ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to open ip_forward (%s)", strerror(errno));
729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (write(fd, (enable ? "1" : "0"), 1) != 1) {
765ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to write ip_forward (%s)", strerror(errno));
7737dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt        close(fd);
789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(fd);
819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
849d10b341a0ba46f108cb96e46691197d778cbc06San Mehatbool TetherController::getIpFwdEnabled() {
859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int fd = open("/proc/sys/net/ipv4/ip_forward", O_RDONLY);
869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (fd < 0) {
885ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to open ip_forward (%s)", strerror(errno));
899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return false;
909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    char enabled;
939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (read(fd, &enabled, 1) != 1) {
945ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Failed to read ip_forward (%s)", strerror(errno));
9537dc4a51774b9c8a95205cb825eae6753170a851Robert Greenwalt        close(fd);
969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(fd);
1009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return (enabled  == '1' ? true : false);
1019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
103bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt#define TETHER_START_CONST_ARG        8
104bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt
1053208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwaltint TetherController::startTethering(int num_addrs, struct in_addr* addrs) {
1069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid != 0) {
1075ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Tethering already started");
1089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        errno = EBUSY;
1099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1127b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Starting tethering services");
1139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    pid_t pid;
1159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int pipefd[2];
1169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (pipe(pipefd) < 0) {
1185ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("pipe failed (%s)", strerror(errno));
1199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    /*
1239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * TODO: Create a monitoring thread to handle and restart
1249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * the daemon if it exits prematurely
1259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     */
1269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if ((pid = fork()) < 0) {
1275ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("fork failed (%s)", strerror(errno));
1289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
1299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!pid) {
1349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (pipefd[0] != STDIN_FILENO) {
1369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
1375ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block                ALOGE("dup2 failed (%s)", strerror(errno));
1389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return -1;
1399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            close(pipefd[0]);
1419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
143bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1;
1443208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        char **args = (char **)malloc(sizeof(char *) * num_processed_args);
1453208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[num_processed_args - 1] = NULL;
1463208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[0] = (char *)"/system/bin/dnsmasq";
147b756f69226d86380ea88b9330356c9fd210dbafePeter Nilsson        args[1] = (char *)"--keep-in-foreground";
1483208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[2] = (char *)"--no-resolv";
1493208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[3] = (char *)"--no-poll";
150bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        args[4] = (char *)"--dhcp-authoritative";
1516df79da87b57437505eedd7fdf5359f9e67c38ddJeff Sharkey        // TODO: pipe through metered status from ConnService
152bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
153bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        args[6] = (char *)"--pid-file";
154bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        args[7] = (char *)"";
1553208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt
156bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        int nextArg = TETHER_START_CONST_ARG;
1573208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        for (int addrIndex=0; addrIndex < num_addrs;) {
1583208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            char *start = strdup(inet_ntoa(addrs[addrIndex++]));
1593208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            char *end = strdup(inet_ntoa(addrs[addrIndex++]));
1603208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt            asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h", start, end);
1613208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        }
1629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1633208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        if (execv(args[0], args)) {
1645ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("execl failed (%s)", strerror(errno));
1659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1665ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Should never get here!");
167ce4f37979316dacf99d5bd3298e870bd35d14aacJP Abgrall        _exit(-1);
1689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
1699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
1709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonPid = pid;
1719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonFd = pipefd[1];
1723d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        applyDnsInterfaces();
1737b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Tethering services running");
1749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
1779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1799d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::stopTethering() {
1809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid == 0) {
1825ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Tethering already stopped");
1839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
1849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1867b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Stopping tethering services");
1879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    kill(mDaemonPid, SIGTERM);
18918737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat    waitpid(mDaemonPid, NULL, 0);
1909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
1919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(mDaemonFd);
1929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
1937b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Tethering services stopped");
1949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
1959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1961994410a3df367c7ce1083dc3f226c8ab68f4fdcMatthew Xie
1979d10b341a0ba46f108cb96e46691197d778cbc06San Mehatbool TetherController::isTetheringStarted() {
1989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return (mDaemonPid == 0 ? false : true);
1999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
201cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root#define MAX_CMD_SIZE 1024
202cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
203667c477133318e4779819d34364194c8e5eaf19cLorenzo Colittiint TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
2049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int i;
205cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root    char daemonCmd[MAX_CMD_SIZE];
2069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
207667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    Fwmark fwmark;
208667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.netId = netId;
209667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.explicitlySelected = true;
210667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.protectedFromVpn = true;
211667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.permission = PERMISSION_SYSTEM;
212667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti
213667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    snprintf(daemonCmd, sizeof(daemonCmd), "update_dns:0x%x", fwmark.intValue);
214cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root    int cmdLen = strlen(daemonCmd);
2159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDnsForwarders->clear();
2179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (i = 0; i < numServers; i++) {
218667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti        ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
2199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        struct in_addr a;
2219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!inet_aton(servers[i], &a)) {
2235ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("Failed to parse DNS server '%s'", servers[i]);
2249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mDnsForwarders->clear();
2259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
2269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
227cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
228ad5b41fae92f20fa9fff334c459dd400de0b8285Nick Kralevich        cmdLen += (strlen(servers[i]) + 1);
229ad5b41fae92f20fa9fff334c459dd400de0b8285Nick Kralevich        if (cmdLen + 1 >= MAX_CMD_SIZE) {
2307b984e3f7e724f8a3547a707210319f3d479f261Steve Block            ALOGD("Too many DNS servers listed");
231cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root            break;
232cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root        }
233cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
2349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        strcat(daemonCmd, ":");
2359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        strcat(daemonCmd, servers[i]);
2369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDnsForwarders->push_back(a);
2379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
239667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    mDnsNetId = netId;
2409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonFd != -1) {
2417b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
2429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
2435ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
2449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mDnsForwarders->clear();
2459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
2469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
2479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
2499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
251667c477133318e4779819d34364194c8e5eaf19cLorenzo Colittiunsigned TetherController::getDnsNetId() {
252667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    return mDnsNetId;
253667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti}
254667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti
2559d10b341a0ba46f108cb96e46691197d778cbc06San MehatNetAddressCollection *TetherController::getDnsForwarders() {
2569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mDnsForwarders;
2579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2593d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwaltint TetherController::applyDnsInterfaces() {
2603d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    char daemonCmd[MAX_CMD_SIZE];
2613d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
2623d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    strcpy(daemonCmd, "update_ifaces");
2633d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    int cmdLen = strlen(daemonCmd);
2643d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    InterfaceCollection::iterator it;
2653d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    bool haveInterfaces = false;
2663d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
2673d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
2683d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        cmdLen += (strlen(*it) + 1);
2693d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        if (cmdLen + 1 >= MAX_CMD_SIZE) {
2703d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            ALOGD("Too many DNS ifaces listed");
2713d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            break;
2723d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        }
2733d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
2743d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        strcat(daemonCmd, ":");
2753d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        strcat(daemonCmd, *it);
2763d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        haveInterfaces = true;
2773d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    }
2783d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
2793d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    if ((mDaemonFd != -1) && haveInterfaces) {
2803d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
2813d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
2823d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
2833d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            return -1;
2843d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        }
2853d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    }
2863d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    return 0;
2873d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt}
2883d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
2899d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::tetherInterface(const char *interface) {
2903d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    ALOGD("tetherInterface(%s)", interface);
29169261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall    if (!isIfaceName(interface)) {
29269261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall        errno = ENOENT;
29369261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall        return -1;
29469261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall    }
2959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mInterfaces->push_back(strdup(interface));
2963d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
2973d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    if (applyDnsInterfaces()) {
2983d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        InterfaceCollection::iterator it;
2993d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
3003d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            if (!strcmp(interface, *it)) {
3013d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt                free(*it);
3023d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt                mInterfaces->erase(it);
3033d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt                break;
3043d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            }
3053d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        }
3063d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        return -1;
3073d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    } else {
3083d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        return 0;
3093d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    }
3109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3129d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::untetherInterface(const char *interface) {
3139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    InterfaceCollection::iterator it;
3149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3153d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    ALOGD("untetherInterface(%s)", interface);
3163d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
3189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!strcmp(interface, *it)) {
3199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            free(*it);
3209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            mInterfaces->erase(it);
3213d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3223d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            return applyDnsInterfaces();
3239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
3249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
3259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    errno = ENOENT;
3269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return -1;
3279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3299d10b341a0ba46f108cb96e46691197d778cbc06San MehatInterfaceCollection *TetherController::getTetheredInterfaceList() {
3309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mInterfaces;
3319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
332