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 <netdb.h> 21 #include <string.h> 22 23 #include <sys/socket.h> 24 #include <sys/stat.h> 25 #include <sys/types.h> 26 #include <sys/wait.h> 27 28 #include <netinet/in.h> 29 #include <arpa/inet.h> 30 31 #define LOG_TAG "TetherController" 32 #include <cutils/log.h> 33 #include <cutils/properties.h> 34 35 #include "Fwmark.h" 36 #include "NetdConstants.h" 37 #include "Permission.h" 38 #include "InterfaceController.h" 39 #include "TetherController.h" 40 41 namespace { 42 43 const char BP_TOOLS_MODE[] = "bp-tools"; 44 const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward"; 45 const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding"; 46 const char SEPARATOR[] = "|"; 47 48 bool writeToFile(const char* filename, const char* value) { 49 int fd = open(filename, O_WRONLY); 50 if (fd < 0) { 51 ALOGE("Failed to open %s: %s", filename, strerror(errno)); 52 return false; 53 } 54 55 const ssize_t len = strlen(value); 56 if (write(fd, value, len) != len) { 57 ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno)); 58 close(fd); 59 return false; 60 } 61 close(fd); 62 return true; 63 } 64 65 bool configureForIPv6Router(const char *interface) { 66 return (InterfaceController::setEnableIPv6(interface, 0) == 0) 67 && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0) 68 && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0) 69 && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0) 70 && (InterfaceController::setEnableIPv6(interface, 1) == 0); 71 } 72 73 void configureForIPv6Client(const char *interface) { 74 InterfaceController::setAcceptIPv6Ra(interface, 1); 75 InterfaceController::setAcceptIPv6Dad(interface, 1); 76 InterfaceController::setIPv6DadTransmits(interface, "1"); 77 InterfaceController::setEnableIPv6(interface, 0); 78 } 79 80 bool inBpToolsMode() { 81 // In BP tools mode, do not disable IP forwarding 82 char bootmode[PROPERTY_VALUE_MAX] = {0}; 83 property_get("ro.bootmode", bootmode, "unknown"); 84 return !strcmp(BP_TOOLS_MODE, bootmode); 85 } 86 87 } // namespace 88 89 TetherController::TetherController() { 90 mDnsNetId = 0; 91 mDaemonFd = -1; 92 mDaemonPid = 0; 93 if (inBpToolsMode()) { 94 enableForwarding(BP_TOOLS_MODE); 95 } else { 96 setIpFwdEnabled(); 97 } 98 } 99 100 TetherController::~TetherController() { 101 mInterfaces.clear(); 102 mDnsForwarders.clear(); 103 mForwardingRequests.clear(); 104 } 105 106 bool TetherController::setIpFwdEnabled() { 107 bool success = true; 108 const char* value = mForwardingRequests.empty() ? "0" : "1"; 109 ALOGD("Setting IP forward enable = %s", value); 110 success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value); 111 success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value); 112 return success; 113 } 114 115 bool TetherController::enableForwarding(const char* requester) { 116 // Don't return an error if this requester already requested forwarding. Only return errors for 117 // things that the caller caller needs to care about, such as "couldn't write to the file to 118 // enable forwarding". 119 mForwardingRequests.insert(requester); 120 return setIpFwdEnabled(); 121 } 122 123 bool TetherController::disableForwarding(const char* requester) { 124 mForwardingRequests.erase(requester); 125 return setIpFwdEnabled(); 126 } 127 128 size_t TetherController::forwardingRequestCount() { 129 return mForwardingRequests.size(); 130 } 131 132 #define TETHER_START_CONST_ARG 8 133 134 int TetherController::startTethering(int num_addrs, char **dhcp_ranges) { 135 if (mDaemonPid != 0) { 136 ALOGE("Tethering already started"); 137 errno = EBUSY; 138 return -1; 139 } 140 141 ALOGD("Starting tethering services"); 142 143 pid_t pid; 144 int pipefd[2]; 145 146 if (pipe(pipefd) < 0) { 147 ALOGE("pipe failed (%s)", strerror(errno)); 148 return -1; 149 } 150 151 /* 152 * TODO: Create a monitoring thread to handle and restart 153 * the daemon if it exits prematurely 154 */ 155 if ((pid = fork()) < 0) { 156 ALOGE("fork failed (%s)", strerror(errno)); 157 close(pipefd[0]); 158 close(pipefd[1]); 159 return -1; 160 } 161 162 if (!pid) { 163 close(pipefd[1]); 164 if (pipefd[0] != STDIN_FILENO) { 165 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) { 166 ALOGE("dup2 failed (%s)", strerror(errno)); 167 return -1; 168 } 169 close(pipefd[0]); 170 } 171 172 int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1; 173 char **args = (char **)malloc(sizeof(char *) * num_processed_args); 174 args[num_processed_args - 1] = NULL; 175 args[0] = (char *)"/system/bin/dnsmasq"; 176 args[1] = (char *)"--keep-in-foreground"; 177 args[2] = (char *)"--no-resolv"; 178 args[3] = (char *)"--no-poll"; 179 args[4] = (char *)"--dhcp-authoritative"; 180 // TODO: pipe through metered status from ConnService 181 args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED"; 182 args[6] = (char *)"--pid-file"; 183 args[7] = (char *)""; 184 185 int nextArg = TETHER_START_CONST_ARG; 186 for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) { 187 asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h", 188 dhcp_ranges[addrIndex], dhcp_ranges[addrIndex+1]); 189 } 190 191 if (execv(args[0], args)) { 192 ALOGE("execl failed (%s)", strerror(errno)); 193 } 194 ALOGE("Should never get here!"); 195 _exit(-1); 196 } else { 197 close(pipefd[0]); 198 mDaemonPid = pid; 199 mDaemonFd = pipefd[1]; 200 applyDnsInterfaces(); 201 ALOGD("Tethering services running"); 202 } 203 204 return 0; 205 } 206 207 int TetherController::stopTethering() { 208 209 if (mDaemonPid == 0) { 210 ALOGE("Tethering already stopped"); 211 return 0; 212 } 213 214 ALOGD("Stopping tethering services"); 215 216 kill(mDaemonPid, SIGTERM); 217 waitpid(mDaemonPid, NULL, 0); 218 mDaemonPid = 0; 219 close(mDaemonFd); 220 mDaemonFd = -1; 221 ALOGD("Tethering services stopped"); 222 return 0; 223 } 224 225 bool TetherController::isTetheringStarted() { 226 return (mDaemonPid == 0 ? false : true); 227 } 228 229 #define MAX_CMD_SIZE 1024 230 231 int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) { 232 int i; 233 char daemonCmd[MAX_CMD_SIZE]; 234 235 Fwmark fwmark; 236 fwmark.netId = netId; 237 fwmark.explicitlySelected = true; 238 fwmark.protectedFromVpn = true; 239 fwmark.permission = PERMISSION_SYSTEM; 240 241 snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue); 242 int cmdLen = strlen(daemonCmd); 243 244 mDnsForwarders.clear(); 245 for (i = 0; i < numServers; i++) { 246 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]); 247 248 addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST }; 249 int ret = getaddrinfo(servers[i], NULL, &hints, &res); 250 freeaddrinfo(res); 251 if (ret) { 252 ALOGE("Failed to parse DNS server '%s'", servers[i]); 253 mDnsForwarders.clear(); 254 errno = EINVAL; 255 return -1; 256 } 257 258 cmdLen += (strlen(servers[i]) + 1); 259 if (cmdLen + 1 >= MAX_CMD_SIZE) { 260 ALOGD("Too many DNS servers listed"); 261 break; 262 } 263 264 strcat(daemonCmd, SEPARATOR); 265 strcat(daemonCmd, servers[i]); 266 mDnsForwarders.push_back(servers[i]); 267 } 268 269 mDnsNetId = netId; 270 if (mDaemonFd != -1) { 271 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 272 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 273 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 274 mDnsForwarders.clear(); 275 errno = EREMOTEIO; 276 return -1; 277 } 278 } 279 return 0; 280 } 281 282 unsigned TetherController::getDnsNetId() { 283 return mDnsNetId; 284 } 285 286 const std::list<std::string> &TetherController::getDnsForwarders() const { 287 return mDnsForwarders; 288 } 289 290 bool TetherController::applyDnsInterfaces() { 291 char daemonCmd[MAX_CMD_SIZE]; 292 293 strcpy(daemonCmd, "update_ifaces"); 294 int cmdLen = strlen(daemonCmd); 295 bool haveInterfaces = false; 296 297 for (const auto &ifname : mInterfaces) { 298 cmdLen += (ifname.size() + 1); 299 if (cmdLen + 1 >= MAX_CMD_SIZE) { 300 ALOGD("Too many DNS ifaces listed"); 301 break; 302 } 303 304 strcat(daemonCmd, SEPARATOR); 305 strcat(daemonCmd, ifname.c_str()); 306 haveInterfaces = true; 307 } 308 309 if ((mDaemonFd != -1) && haveInterfaces) { 310 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 311 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 312 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 313 return false; 314 } 315 } 316 return true; 317 } 318 319 int TetherController::tetherInterface(const char *interface) { 320 ALOGD("tetherInterface(%s)", interface); 321 if (!isIfaceName(interface)) { 322 errno = ENOENT; 323 return -1; 324 } 325 326 if (!configureForIPv6Router(interface)) { 327 configureForIPv6Client(interface); 328 return -1; 329 } 330 mInterfaces.push_back(interface); 331 332 if (!applyDnsInterfaces()) { 333 mInterfaces.pop_back(); 334 configureForIPv6Client(interface); 335 return -1; 336 } else { 337 return 0; 338 } 339 } 340 341 int TetherController::untetherInterface(const char *interface) { 342 ALOGD("untetherInterface(%s)", interface); 343 344 for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) { 345 if (!strcmp(interface, it->c_str())) { 346 mInterfaces.erase(it); 347 348 configureForIPv6Client(interface); 349 return applyDnsInterfaces() ? 0 : -1; 350 } 351 } 352 errno = ENOENT; 353 return -1; 354 } 355 356 const std::list<std::string> &TetherController::getTetheredInterfaceList() const { 357 return mInterfaces; 358 } 359