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