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 39 TetherController::TetherController() { 40 mInterfaces = new InterfaceCollection(); 41 mDnsNetId = 0; 42 mDnsForwarders = new NetAddressCollection(); 43 mDaemonFd = -1; 44 mDaemonPid = 0; 45 } 46 47 TetherController::~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 58 int 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 84 bool 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 105 int 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 } 162 163 if (execv(args[0], args)) { 164 ALOGE("execl failed (%s)", strerror(errno)); 165 } 166 ALOGE("Should never get here!"); 167 _exit(-1); 168 } else { 169 close(pipefd[0]); 170 mDaemonPid = pid; 171 mDaemonFd = pipefd[1]; 172 applyDnsInterfaces(); 173 ALOGD("Tethering services running"); 174 } 175 176 return 0; 177 } 178 179 int TetherController::stopTethering() { 180 181 if (mDaemonPid == 0) { 182 ALOGE("Tethering already stopped"); 183 return 0; 184 } 185 186 ALOGD("Stopping tethering services"); 187 188 kill(mDaemonPid, SIGTERM); 189 waitpid(mDaemonPid, NULL, 0); 190 mDaemonPid = 0; 191 close(mDaemonFd); 192 mDaemonFd = -1; 193 ALOGD("Tethering services stopped"); 194 return 0; 195 } 196 197 bool TetherController::isTetheringStarted() { 198 return (mDaemonPid == 0 ? false : true); 199 } 200 201 #define MAX_CMD_SIZE 1024 202 203 int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) { 204 int i; 205 char daemonCmd[MAX_CMD_SIZE]; 206 207 Fwmark fwmark; 208 fwmark.netId = netId; 209 fwmark.explicitlySelected = true; 210 fwmark.protectedFromVpn = true; 211 fwmark.permission = PERMISSION_SYSTEM; 212 213 snprintf(daemonCmd, sizeof(daemonCmd), "update_dns:0x%x", fwmark.intValue); 214 int cmdLen = strlen(daemonCmd); 215 216 mDnsForwarders->clear(); 217 for (i = 0; i < numServers; i++) { 218 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]); 219 220 struct in_addr a; 221 222 if (!inet_aton(servers[i], &a)) { 223 ALOGE("Failed to parse DNS server '%s'", servers[i]); 224 mDnsForwarders->clear(); 225 return -1; 226 } 227 228 cmdLen += (strlen(servers[i]) + 1); 229 if (cmdLen + 1 >= MAX_CMD_SIZE) { 230 ALOGD("Too many DNS servers listed"); 231 break; 232 } 233 234 strcat(daemonCmd, ":"); 235 strcat(daemonCmd, servers[i]); 236 mDnsForwarders->push_back(a); 237 } 238 239 mDnsNetId = netId; 240 if (mDaemonFd != -1) { 241 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 242 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 243 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 244 mDnsForwarders->clear(); 245 return -1; 246 } 247 } 248 return 0; 249 } 250 251 unsigned TetherController::getDnsNetId() { 252 return mDnsNetId; 253 } 254 255 NetAddressCollection *TetherController::getDnsForwarders() { 256 return mDnsForwarders; 257 } 258 259 int TetherController::applyDnsInterfaces() { 260 char daemonCmd[MAX_CMD_SIZE]; 261 262 strcpy(daemonCmd, "update_ifaces"); 263 int cmdLen = strlen(daemonCmd); 264 InterfaceCollection::iterator it; 265 bool haveInterfaces = false; 266 267 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 268 cmdLen += (strlen(*it) + 1); 269 if (cmdLen + 1 >= MAX_CMD_SIZE) { 270 ALOGD("Too many DNS ifaces listed"); 271 break; 272 } 273 274 strcat(daemonCmd, ":"); 275 strcat(daemonCmd, *it); 276 haveInterfaces = true; 277 } 278 279 if ((mDaemonFd != -1) && haveInterfaces) { 280 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 281 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 282 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 283 return -1; 284 } 285 } 286 return 0; 287 } 288 289 int TetherController::tetherInterface(const char *interface) { 290 ALOGD("tetherInterface(%s)", interface); 291 if (!isIfaceName(interface)) { 292 errno = ENOENT; 293 return -1; 294 } 295 mInterfaces->push_back(strdup(interface)); 296 297 if (applyDnsInterfaces()) { 298 InterfaceCollection::iterator it; 299 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 300 if (!strcmp(interface, *it)) { 301 free(*it); 302 mInterfaces->erase(it); 303 break; 304 } 305 } 306 return -1; 307 } else { 308 return 0; 309 } 310 } 311 312 int TetherController::untetherInterface(const char *interface) { 313 InterfaceCollection::iterator it; 314 315 ALOGD("untetherInterface(%s)", interface); 316 317 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 318 if (!strcmp(interface, *it)) { 319 free(*it); 320 mInterfaces->erase(it); 321 322 return applyDnsInterfaces(); 323 } 324 } 325 errno = ENOENT; 326 return -1; 327 } 328 329 InterfaceCollection *TetherController::getTetheredInterfaceList() { 330 return mInterfaces; 331 } 332