TetherController.cpp revision a9d791f48e3472400ffad73dca88c28fb2f7aaa7
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdlib.h> 18#include <errno.h> 19#include <fcntl.h> 20#include <string.h> 21 22#include <sys/socket.h> 23#include <sys/stat.h> 24#include <sys/types.h> 25#include <sys/wait.h> 26 27#include <netinet/in.h> 28#include <arpa/inet.h> 29 30#define LOG_TAG "TetherController" 31#include <cutils/log.h> 32#include <cutils/properties.h> 33 34#include "Fwmark.h" 35#include "NetdConstants.h" 36#include "Permission.h" 37#include "TetherController.h" 38 39TetherController::TetherController() { 40 mInterfaces = new InterfaceCollection(); 41 mDnsNetId = 0; 42 mDnsForwarders = new NetAddressCollection(); 43 mDaemonFd = -1; 44 mDaemonPid = 0; 45} 46 47TetherController::~TetherController() { 48 InterfaceCollection::iterator it; 49 50 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 51 free(*it); 52 } 53 mInterfaces->clear(); 54 55 mDnsForwarders->clear(); 56} 57 58int TetherController::setIpFwdEnabled(bool enable) { 59 60 ALOGD("Setting IP forward enable = %d", enable); 61 62 // In BP tools mode, do not disable IP forwarding 63 char bootmode[PROPERTY_VALUE_MAX] = {0}; 64 property_get("ro.bootmode", bootmode, "unknown"); 65 if ((enable == false) && (0 == strcmp("bp-tools", bootmode))) { 66 return 0; 67 } 68 69 int fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY); 70 if (fd < 0) { 71 ALOGE("Failed to open ip_forward (%s)", strerror(errno)); 72 return -1; 73 } 74 75 if (write(fd, (enable ? "1" : "0"), 1) != 1) { 76 ALOGE("Failed to write ip_forward (%s)", strerror(errno)); 77 close(fd); 78 return -1; 79 } 80 close(fd); 81 return 0; 82} 83 84bool TetherController::getIpFwdEnabled() { 85 int fd = open("/proc/sys/net/ipv4/ip_forward", O_RDONLY); 86 87 if (fd < 0) { 88 ALOGE("Failed to open ip_forward (%s)", strerror(errno)); 89 return false; 90 } 91 92 char enabled; 93 if (read(fd, &enabled, 1) != 1) { 94 ALOGE("Failed to read ip_forward (%s)", strerror(errno)); 95 close(fd); 96 return -1; 97 } 98 99 close(fd); 100 return (enabled == '1' ? true : false); 101} 102 103#define TETHER_START_CONST_ARG 8 104 105int TetherController::startTethering(int num_addrs, struct in_addr* addrs) { 106 if (mDaemonPid != 0) { 107 ALOGE("Tethering already started"); 108 errno = EBUSY; 109 return -1; 110 } 111 112 ALOGD("Starting tethering services"); 113 114 pid_t pid; 115 int pipefd[2]; 116 117 if (pipe(pipefd) < 0) { 118 ALOGE("pipe failed (%s)", strerror(errno)); 119 return -1; 120 } 121 122 /* 123 * TODO: Create a monitoring thread to handle and restart 124 * the daemon if it exits prematurely 125 */ 126 if ((pid = fork()) < 0) { 127 ALOGE("fork failed (%s)", strerror(errno)); 128 close(pipefd[0]); 129 close(pipefd[1]); 130 return -1; 131 } 132 133 if (!pid) { 134 close(pipefd[1]); 135 if (pipefd[0] != STDIN_FILENO) { 136 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) { 137 ALOGE("dup2 failed (%s)", strerror(errno)); 138 return -1; 139 } 140 close(pipefd[0]); 141 } 142 143 int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1; 144 char **args = (char **)malloc(sizeof(char *) * num_processed_args); 145 args[num_processed_args - 1] = NULL; 146 args[0] = (char *)"/system/bin/dnsmasq"; 147 args[1] = (char *)"--keep-in-foreground"; 148 args[2] = (char *)"--no-resolv"; 149 args[3] = (char *)"--no-poll"; 150 args[4] = (char *)"--dhcp-authoritative"; 151 // TODO: pipe through metered status from ConnService 152 args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED"; 153 args[6] = (char *)"--pid-file"; 154 args[7] = (char *)""; 155 156 int nextArg = TETHER_START_CONST_ARG; 157 for (int addrIndex=0; addrIndex < num_addrs;) { 158 char *start = strdup(inet_ntoa(addrs[addrIndex++])); 159 char *end = strdup(inet_ntoa(addrs[addrIndex++])); 160 asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h", start, end); 161 free(start); 162 free(end); 163 } 164 165 if (execv(args[0], args)) { 166 ALOGE("execl failed (%s)", strerror(errno)); 167 } 168 ALOGE("Should never get here!"); 169 _exit(-1); 170 } else { 171 close(pipefd[0]); 172 mDaemonPid = pid; 173 mDaemonFd = pipefd[1]; 174 applyDnsInterfaces(); 175 ALOGD("Tethering services running"); 176 } 177 178 return 0; 179} 180 181int TetherController::stopTethering() { 182 183 if (mDaemonPid == 0) { 184 ALOGE("Tethering already stopped"); 185 return 0; 186 } 187 188 ALOGD("Stopping tethering services"); 189 190 kill(mDaemonPid, SIGTERM); 191 waitpid(mDaemonPid, NULL, 0); 192 mDaemonPid = 0; 193 close(mDaemonFd); 194 mDaemonFd = -1; 195 ALOGD("Tethering services stopped"); 196 return 0; 197} 198 199bool TetherController::isTetheringStarted() { 200 return (mDaemonPid == 0 ? false : true); 201} 202 203#define MAX_CMD_SIZE 1024 204 205int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) { 206 int i; 207 char daemonCmd[MAX_CMD_SIZE]; 208 209 Fwmark fwmark; 210 fwmark.netId = netId; 211 fwmark.explicitlySelected = true; 212 fwmark.protectedFromVpn = true; 213 fwmark.permission = PERMISSION_SYSTEM; 214 215 snprintf(daemonCmd, sizeof(daemonCmd), "update_dns:0x%x", fwmark.intValue); 216 int cmdLen = strlen(daemonCmd); 217 218 mDnsForwarders->clear(); 219 for (i = 0; i < numServers; i++) { 220 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]); 221 222 struct in_addr a; 223 224 if (!inet_aton(servers[i], &a)) { 225 ALOGE("Failed to parse DNS server '%s'", servers[i]); 226 mDnsForwarders->clear(); 227 return -1; 228 } 229 230 cmdLen += (strlen(servers[i]) + 1); 231 if (cmdLen + 1 >= MAX_CMD_SIZE) { 232 ALOGD("Too many DNS servers listed"); 233 break; 234 } 235 236 strcat(daemonCmd, ":"); 237 strcat(daemonCmd, servers[i]); 238 mDnsForwarders->push_back(a); 239 } 240 241 mDnsNetId = netId; 242 if (mDaemonFd != -1) { 243 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 244 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 245 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 246 mDnsForwarders->clear(); 247 return -1; 248 } 249 } 250 return 0; 251} 252 253unsigned TetherController::getDnsNetId() { 254 return mDnsNetId; 255} 256 257NetAddressCollection *TetherController::getDnsForwarders() { 258 return mDnsForwarders; 259} 260 261int TetherController::applyDnsInterfaces() { 262 char daemonCmd[MAX_CMD_SIZE]; 263 264 strcpy(daemonCmd, "update_ifaces"); 265 int cmdLen = strlen(daemonCmd); 266 InterfaceCollection::iterator it; 267 bool haveInterfaces = false; 268 269 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 270 cmdLen += (strlen(*it) + 1); 271 if (cmdLen + 1 >= MAX_CMD_SIZE) { 272 ALOGD("Too many DNS ifaces listed"); 273 break; 274 } 275 276 strcat(daemonCmd, ":"); 277 strcat(daemonCmd, *it); 278 haveInterfaces = true; 279 } 280 281 if ((mDaemonFd != -1) && haveInterfaces) { 282 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 283 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 284 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 285 return -1; 286 } 287 } 288 return 0; 289} 290 291int TetherController::tetherInterface(const char *interface) { 292 ALOGD("tetherInterface(%s)", interface); 293 if (!isIfaceName(interface)) { 294 errno = ENOENT; 295 return -1; 296 } 297 mInterfaces->push_back(strdup(interface)); 298 299 if (applyDnsInterfaces()) { 300 InterfaceCollection::iterator it; 301 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 302 if (!strcmp(interface, *it)) { 303 free(*it); 304 mInterfaces->erase(it); 305 break; 306 } 307 } 308 return -1; 309 } else { 310 return 0; 311 } 312} 313 314int TetherController::untetherInterface(const char *interface) { 315 InterfaceCollection::iterator it; 316 317 ALOGD("untetherInterface(%s)", interface); 318 319 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 320 if (!strcmp(interface, *it)) { 321 free(*it); 322 mInterfaces->erase(it); 323 324 return applyDnsInterfaces(); 325 } 326 } 327 errno = ENOENT; 328 return -1; 329} 330 331InterfaceCollection *TetherController::getTetheredInterfaceList() { 332 return mInterfaces; 333} 334