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>
20c2841283740e5026d6ee54ebe87b202c93c26d93Lorenzo Colitti#include <netdb.h>
21ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h>
2218737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat
239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <sys/socket.h>
249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <sys/stat.h>
2518737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat#include <sys/types.h>
2618737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat#include <sys/wait.h>
2718737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat
289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <netinet/in.h>
299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <arpa/inet.h>
309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#define LOG_TAG "TetherController"
329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include <cutils/log.h>
336b858eb3b9b94b19c5153311e10b6e832722fb8eKazuhiro Ondo#include <cutils/properties.h>
349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
35667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti#include "Fwmark.h"
3669261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall#include "NetdConstants.h"
37667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti#include "Permission.h"
381d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline#include "InterfaceController.h"
393c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti#include "NetworkController.h"
409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat#include "TetherController.h"
419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
42799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colittinamespace {
43799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti
441d065ba8b62988b5b92517984d4761c32f00abd3Erik Klineconst char BP_TOOLS_MODE[] = "bp-tools";
451d065ba8b62988b5b92517984d4761c32f00abd3Erik Klineconst char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
461d065ba8b62988b5b92517984d4761c32f00abd3Erik Klineconst char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
471d065ba8b62988b5b92517984d4761c32f00abd3Erik Klineconst char SEPARATOR[] = "|";
48799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti
49799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colittibool writeToFile(const char* filename, const char* value) {
50b95c60c78d3a58d04439530c5a0e9197a40cb87bNick Kralevich    int fd = open(filename, O_WRONLY | O_CLOEXEC);
51afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray    if (fd < 0) {
52afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray        ALOGE("Failed to open %s: %s", filename, strerror(errno));
53afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray        return false;
54afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray    }
55afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray
56afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray    const ssize_t len = strlen(value);
57afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray    if (write(fd, value, len) != len) {
58afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray        ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
59afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray        close(fd);
60afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray        return false;
61afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray    }
62afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray    close(fd);
63afd4037d7d7802d2ecc0494901ac17134a27aa1fNicolas Geoffray    return true;
64799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti}
65799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti
661d065ba8b62988b5b92517984d4761c32f00abd3Erik Klinebool configureForIPv6Router(const char *interface) {
671d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    return (InterfaceController::setEnableIPv6(interface, 0) == 0)
681d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
696cddf5193149ae8a072e8e0c9bf4a97cab3feb62Erik Kline            && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0)
706cddf5193149ae8a072e8e0c9bf4a97cab3feb62Erik Kline            && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0)
711d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            && (InterfaceController::setEnableIPv6(interface, 1) == 0);
721d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline}
731d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline
741d065ba8b62988b5b92517984d4761c32f00abd3Erik Klinevoid configureForIPv6Client(const char *interface) {
751d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    InterfaceController::setAcceptIPv6Ra(interface, 1);
766cddf5193149ae8a072e8e0c9bf4a97cab3feb62Erik Kline    InterfaceController::setAcceptIPv6Dad(interface, 1);
776cddf5193149ae8a072e8e0c9bf4a97cab3feb62Erik Kline    InterfaceController::setIPv6DadTransmits(interface, "1");
781d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    InterfaceController::setEnableIPv6(interface, 0);
791d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline}
801d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline
81799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colittibool inBpToolsMode() {
82799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    // In BP tools mode, do not disable IP forwarding
83799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    char bootmode[PROPERTY_VALUE_MAX] = {0};
84799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    property_get("ro.bootmode", bootmode, "unknown");
85799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    return !strcmp(BP_TOOLS_MODE, bootmode);
86799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti}
87799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti
88799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti}  // namespace
89799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti
903c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colittinamespace android {
913c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colittinamespace net {
923c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti
9387475a1471373b72ffc9f81f17dfd7884723fa86Sreeram RamachandranTetherController::TetherController() {
94667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    mDnsNetId = 0;
959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
97799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    if (inBpToolsMode()) {
98799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti        enableForwarding(BP_TOOLS_MODE);
99799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    } else {
100799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti        setIpFwdEnabled();
101799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    }
1029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1049d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController::~TetherController() {
1051d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    mInterfaces.clear();
1061d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    mDnsForwarders.clear();
107799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    mForwardingRequests.clear();
1089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
110799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colittibool TetherController::setIpFwdEnabled() {
111799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    bool success = true;
112799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    const char* value = mForwardingRequests.empty() ? "0" : "1";
113799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    ALOGD("Setting IP forward enable = %s", value);
114799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
115799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
116799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    return success;
1179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
118d161406141619f84d94b2ecee618569cbbabcb30Elliott Hughes
119799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colittibool TetherController::enableForwarding(const char* requester) {
120799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    // Don't return an error if this requester already requested forwarding. Only return errors for
121799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    // things that the caller caller needs to care about, such as "couldn't write to the file to
122799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    // enable forwarding".
123799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    mForwardingRequests.insert(requester);
124799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    return setIpFwdEnabled();
1259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
127799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colittibool TetherController::disableForwarding(const char* requester) {
128799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    mForwardingRequests.erase(requester);
129799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    return setIpFwdEnabled();
130799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti}
1319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
132799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colittisize_t TetherController::forwardingRequestCount() {
133799625cd5b0a2191632f5b042bf9ff559c18a848Lorenzo Colitti    return mForwardingRequests.size();
1349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
1359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1363c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti#define TETHER_START_CONST_ARG        10
137bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt
13813fa01fab904679970e4b95357f8eed7327b6d49Erik Klineint TetherController::startTethering(int num_addrs, char **dhcp_ranges) {
1399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid != 0) {
1405ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Tethering already started");
1419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        errno = EBUSY;
1429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1457b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Starting tethering services");
1469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    pid_t pid;
1489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int pipefd[2];
1499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (pipe(pipefd) < 0) {
1515ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("pipe failed (%s)", strerror(errno));
1529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    /*
1569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * TODO: Create a monitoring thread to handle and restart
1579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     * the daemon if it exits prematurely
1589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat     */
1599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if ((pid = fork()) < 0) {
1605ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("fork failed (%s)", strerror(errno));
1619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
1629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return -1;
1649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!pid) {
1679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[1]);
1689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (pipefd[0] != STDIN_FILENO) {
1699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
1705ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block                ALOGE("dup2 failed (%s)", strerror(errno));
1719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return -1;
1729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            close(pipefd[0]);
1749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1763c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        Fwmark fwmark;
1773c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        fwmark.netId = NetworkController::LOCAL_NET_ID;
1783c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        fwmark.explicitlySelected = true;
1793c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        fwmark.protectedFromVpn = true;
1803c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        fwmark.permission = PERMISSION_SYSTEM;
1813c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        char markStr[UINT32_HEX_STRLEN];
1823c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue);
1833c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti
184bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1;
1853208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        char **args = (char **)malloc(sizeof(char *) * num_processed_args);
1863208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[num_processed_args - 1] = NULL;
1873208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[0] = (char *)"/system/bin/dnsmasq";
188b756f69226d86380ea88b9330356c9fd210dbafePeter Nilsson        args[1] = (char *)"--keep-in-foreground";
1893208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[2] = (char *)"--no-resolv";
1903208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        args[3] = (char *)"--no-poll";
191bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        args[4] = (char *)"--dhcp-authoritative";
1926df79da87b57437505eedd7fdf5359f9e67c38ddJeff Sharkey        // TODO: pipe through metered status from ConnService
193bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
194bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        args[6] = (char *)"--pid-file";
1953c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        args[7] = (char *)"--listen-mark";
1963c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        args[8] = (char *)markStr;
1973c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti        args[9] = (char *)"";
1983208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt
199bc775ed3aca7f14fb5e2b66dfdcb5da87ce9b4d5Dmitry Shmidt        int nextArg = TETHER_START_CONST_ARG;
20013fa01fab904679970e4b95357f8eed7327b6d49Erik Kline        for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
20113fa01fab904679970e4b95357f8eed7327b6d49Erik Kline            asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h",
20213fa01fab904679970e4b95357f8eed7327b6d49Erik Kline                     dhcp_ranges[addrIndex], dhcp_ranges[addrIndex+1]);
2033208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        }
2049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2053208ea0b6cce28e7aef8459d548fd86df329e34fRobert Greenwalt        if (execv(args[0], args)) {
2065ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("execl failed (%s)", strerror(errno));
2079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
2085ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Should never get here!");
209ce4f37979316dacf99d5bd3298e870bd35d14aacJP Abgrall        _exit(-1);
2109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
2119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        close(pipefd[0]);
2129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonPid = pid;
2139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        mDaemonFd = pipefd[1];
2143d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        applyDnsInterfaces();
2157b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Tethering services running");
2169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
2199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2219d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::stopTethering() {
2229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonPid == 0) {
2245ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block        ALOGE("Tethering already stopped");
2259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
2269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2287b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Stopping tethering services");
2299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    kill(mDaemonPid, SIGTERM);
23118737845d3c6a60edd6f75ac441a1b3fed6d66a7San Mehat    waitpid(mDaemonPid, NULL, 0);
2329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonPid = 0;
2339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    close(mDaemonFd);
2349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    mDaemonFd = -1;
2357b984e3f7e724f8a3547a707210319f3d479f261Steve Block    ALOGD("Tethering services stopped");
2369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
2379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2381994410a3df367c7ce1083dc3f226c8ab68f4fdcMatthew Xie
2399d10b341a0ba46f108cb96e46691197d778cbc06San Mehatbool TetherController::isTetheringStarted() {
2409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return (mDaemonPid == 0 ? false : true);
2419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
243cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root#define MAX_CMD_SIZE 1024
244cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
245667c477133318e4779819d34364194c8e5eaf19cLorenzo Colittiint TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
2469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int i;
247cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root    char daemonCmd[MAX_CMD_SIZE];
2489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
249667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    Fwmark fwmark;
250667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.netId = netId;
251667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.explicitlySelected = true;
252667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.protectedFromVpn = true;
253667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    fwmark.permission = PERMISSION_SYSTEM;
254667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti
25513fa01fab904679970e4b95357f8eed7327b6d49Erik Kline    snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue);
256cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root    int cmdLen = strlen(daemonCmd);
2579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2581d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    mDnsForwarders.clear();
2599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    for (i = 0; i < numServers; i++) {
260667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti        ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
2619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
262c2841283740e5026d6ee54ebe87b202c93c26d93Lorenzo Colitti        addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST };
263c2841283740e5026d6ee54ebe87b202c93c26d93Lorenzo Colitti        int ret = getaddrinfo(servers[i], NULL, &hints, &res);
264c2841283740e5026d6ee54ebe87b202c93c26d93Lorenzo Colitti        freeaddrinfo(res);
265c2841283740e5026d6ee54ebe87b202c93c26d93Lorenzo Colitti        if (ret) {
2665ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("Failed to parse DNS server '%s'", servers[i]);
2671d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            mDnsForwarders.clear();
268c2841283740e5026d6ee54ebe87b202c93c26d93Lorenzo Colitti            errno = EINVAL;
2699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
2709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
271cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
272ad5b41fae92f20fa9fff334c459dd400de0b8285Nick Kralevich        cmdLen += (strlen(servers[i]) + 1);
273ad5b41fae92f20fa9fff334c459dd400de0b8285Nick Kralevich        if (cmdLen + 1 >= MAX_CMD_SIZE) {
2747b984e3f7e724f8a3547a707210319f3d479f261Steve Block            ALOGD("Too many DNS servers listed");
275cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root            break;
276cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root        }
277cf52faf90be32aab3d0c4736a95f26923227e475Kenny Root
27813fa01fab904679970e4b95357f8eed7327b6d49Erik Kline        strcat(daemonCmd, SEPARATOR);
2799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        strcat(daemonCmd, servers[i]);
2801d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        mDnsForwarders.push_back(servers[i]);
2819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
283667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    mDnsNetId = netId;
2849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (mDaemonFd != -1) {
2857b984e3f7e724f8a3547a707210319f3d479f261Steve Block        ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
2869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
2875ea0c05a1e7d8e664b808aa1bb1efd08fdb2fb13Steve Block            ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
2881d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            mDnsForwarders.clear();
289c2841283740e5026d6ee54ebe87b202c93c26d93Lorenzo Colitti            errno = EREMOTEIO;
2909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return -1;
2919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
2929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return 0;
2949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
2959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
296667c477133318e4779819d34364194c8e5eaf19cLorenzo Colittiunsigned TetherController::getDnsNetId() {
297667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti    return mDnsNetId;
298667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti}
299667c477133318e4779819d34364194c8e5eaf19cLorenzo Colitti
3001d065ba8b62988b5b92517984d4761c32f00abd3Erik Klineconst std::list<std::string> &TetherController::getDnsForwarders() const {
3019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mDnsForwarders;
3029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3041d065ba8b62988b5b92517984d4761c32f00abd3Erik Klinebool TetherController::applyDnsInterfaces() {
3053d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    char daemonCmd[MAX_CMD_SIZE];
3063d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3073d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    strcpy(daemonCmd, "update_ifaces");
3083d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    int cmdLen = strlen(daemonCmd);
3093d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    bool haveInterfaces = false;
3103d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3111d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    for (const auto &ifname : mInterfaces) {
3121d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        cmdLen += (ifname.size() + 1);
3133d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        if (cmdLen + 1 >= MAX_CMD_SIZE) {
3143d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            ALOGD("Too many DNS ifaces listed");
3153d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            break;
3163d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        }
3173d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
31813fa01fab904679970e4b95357f8eed7327b6d49Erik Kline        strcat(daemonCmd, SEPARATOR);
3191d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        strcat(daemonCmd, ifname.c_str());
3203d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        haveInterfaces = true;
3213d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    }
3223d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3233d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    if ((mDaemonFd != -1) && haveInterfaces) {
3243d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
3253d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
3263d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt            ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
3271d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            return false;
3283d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        }
3293d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    }
3301d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    return true;
3313d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt}
3323d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3339d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::tetherInterface(const char *interface) {
3343d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    ALOGD("tetherInterface(%s)", interface);
33569261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall    if (!isIfaceName(interface)) {
33669261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall        errno = ENOENT;
33769261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall        return -1;
33869261cb65186e27dfbdc1e3eec796437f9968ff9JP Abgrall    }
3391d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline
3401d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    if (!configureForIPv6Router(interface)) {
3411d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        configureForIPv6Client(interface);
3421d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        return -1;
3431d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    }
3441d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    mInterfaces.push_back(interface);
3451d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline
3461d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    if (!applyDnsInterfaces()) {
3471d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        mInterfaces.pop_back();
3481d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        configureForIPv6Client(interface);
3493d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        return -1;
3503d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    } else {
3513d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt        return 0;
3523d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    }
3539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3559d10b341a0ba46f108cb96e46691197d778cbc06San Mehatint TetherController::untetherInterface(const char *interface) {
3563d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt    ALOGD("untetherInterface(%s)", interface);
3573d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3581d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline    for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
3591d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline        if (!strcmp(interface, it->c_str())) {
3601d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            mInterfaces.erase(it);
3613d4c7585e35a93d9608fce8cc056b7eee9123a53Robert Greenwalt
3621d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            configureForIPv6Client(interface);
3631d065ba8b62988b5b92517984d4761c32f00abd3Erik Kline            return applyDnsInterfaces() ? 0 : -1;
3649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
3659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
3669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    errno = ENOENT;
3679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return -1;
3689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
3701d065ba8b62988b5b92517984d4761c32f00abd3Erik Klineconst std::list<std::string> &TetherController::getTetheredInterfaceList() const {
3719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    return mInterfaces;
3729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat}
3733c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti
3743c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti}  // namespace net
3753c57e25ba7380a4fcacea33ac1ee1ee434957d2bLorenzo Colitti}  // namespace android
376