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