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