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 "TetherController.h" 35 36TetherController::TetherController() { 37 mInterfaces = new InterfaceCollection(); 38 mDnsForwarders = new NetAddressCollection(); 39 mDaemonFd = -1; 40 mDaemonPid = 0; 41 mDhcpcdPid = 0; 42} 43 44TetherController::~TetherController() { 45 InterfaceCollection::iterator it; 46 47 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 48 free(*it); 49 } 50 mInterfaces->clear(); 51 52 mDnsForwarders->clear(); 53} 54 55int TetherController::setIpFwdEnabled(bool enable) { 56 57 ALOGD("Setting IP forward enable = %d", enable); 58 59 // In BP tools mode, do not disable IP forwarding 60 char bootmode[PROPERTY_VALUE_MAX] = {0}; 61 property_get("ro.bootmode", bootmode, "unknown"); 62 if ((enable == false) && (0 == strcmp("bp-tools", bootmode))) { 63 return 0; 64 } 65 66 int fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY); 67 if (fd < 0) { 68 ALOGE("Failed to open ip_forward (%s)", strerror(errno)); 69 return -1; 70 } 71 72 if (write(fd, (enable ? "1" : "0"), 1) != 1) { 73 ALOGE("Failed to write ip_forward (%s)", strerror(errno)); 74 close(fd); 75 return -1; 76 } 77 close(fd); 78 return 0; 79} 80 81bool TetherController::getIpFwdEnabled() { 82 int fd = open("/proc/sys/net/ipv4/ip_forward", O_RDONLY); 83 84 if (fd < 0) { 85 ALOGE("Failed to open ip_forward (%s)", strerror(errno)); 86 return false; 87 } 88 89 char enabled; 90 if (read(fd, &enabled, 1) != 1) { 91 ALOGE("Failed to read ip_forward (%s)", strerror(errno)); 92 close(fd); 93 return -1; 94 } 95 96 close(fd); 97 return (enabled == '1' ? true : false); 98} 99 100int TetherController::startTethering(int num_addrs, struct in_addr* addrs) { 101 if (mDaemonPid != 0) { 102 ALOGE("Tethering already started"); 103 errno = EBUSY; 104 return -1; 105 } 106 107 ALOGD("Starting tethering services"); 108 109 pid_t pid; 110 int pipefd[2]; 111 112 if (pipe(pipefd) < 0) { 113 ALOGE("pipe failed (%s)", strerror(errno)); 114 return -1; 115 } 116 117 /* 118 * TODO: Create a monitoring thread to handle and restart 119 * the daemon if it exits prematurely 120 */ 121 if ((pid = fork()) < 0) { 122 ALOGE("fork failed (%s)", strerror(errno)); 123 close(pipefd[0]); 124 close(pipefd[1]); 125 return -1; 126 } 127 128 if (!pid) { 129 close(pipefd[1]); 130 if (pipefd[0] != STDIN_FILENO) { 131 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) { 132 ALOGE("dup2 failed (%s)", strerror(errno)); 133 return -1; 134 } 135 close(pipefd[0]); 136 } 137 138 int num_processed_args = 7 + (num_addrs/2) + 1; // 1 null for termination 139 char **args = (char **)malloc(sizeof(char *) * num_processed_args); 140 args[num_processed_args - 1] = NULL; 141 args[0] = (char *)"/system/bin/dnsmasq"; 142 args[1] = (char *)"--keep-in-foreground"; 143 args[2] = (char *)"--no-resolv"; 144 args[3] = (char *)"--no-poll"; 145 // TODO: pipe through metered status from ConnService 146 args[4] = (char *)"--dhcp-option-force=43,ANDROID_METERED"; 147 args[5] = (char *)"--pid-file"; 148 args[6] = (char *)""; 149 150 int nextArg = 7; 151 for (int addrIndex=0; addrIndex < num_addrs;) { 152 char *start = strdup(inet_ntoa(addrs[addrIndex++])); 153 char *end = strdup(inet_ntoa(addrs[addrIndex++])); 154 asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h", start, end); 155 } 156 157 if (execv(args[0], args)) { 158 ALOGE("execl failed (%s)", strerror(errno)); 159 } 160 ALOGE("Should never get here!"); 161 free(args); 162 return 0; 163 } else { 164 close(pipefd[0]); 165 mDaemonPid = pid; 166 mDaemonFd = pipefd[1]; 167 ALOGD("Tethering services running"); 168 } 169 170 return 0; 171} 172 173int TetherController::stopTethering() { 174 175 if (mDaemonPid == 0) { 176 ALOGE("Tethering already stopped"); 177 return 0; 178 } 179 180 ALOGD("Stopping tethering services"); 181 182 kill(mDaemonPid, SIGTERM); 183 waitpid(mDaemonPid, NULL, 0); 184 mDaemonPid = 0; 185 close(mDaemonFd); 186 mDaemonFd = -1; 187 ALOGD("Tethering services stopped"); 188 return 0; 189} 190 191// TODO(BT) remove 192int TetherController::startReverseTethering(const char* iface) { 193 if (mDhcpcdPid != 0) { 194 ALOGE("Reverse tethering already started"); 195 errno = EBUSY; 196 return -1; 197 } 198 199 ALOGD("TetherController::startReverseTethering, Starting reverse tethering"); 200 201 /* 202 * TODO: Create a monitoring thread to handle and restart 203 * the daemon if it exits prematurely 204 */ 205 //cleanup the dhcp result 206 char dhcp_result_name[64]; 207 snprintf(dhcp_result_name, sizeof(dhcp_result_name) - 1, "dhcp.%s.result", iface); 208 property_set(dhcp_result_name, ""); 209 210 pid_t pid; 211 if ((pid = fork()) < 0) { 212 ALOGE("fork failed (%s)", strerror(errno)); 213 return -1; 214 } 215 216 if (!pid) { 217 218 char *args[10]; 219 int argc = 0; 220 args[argc++] = "/system/bin/dhcpcd"; 221 char host_name[128]; 222 if (property_get("net.hostname", host_name, NULL) && (host_name[0] != '\0')) 223 { 224 args[argc++] = "-h"; 225 args[argc++] = host_name; 226 } 227 args[argc++] = (char*)iface; 228 args[argc] = NULL; 229 if (execv(args[0], args)) { 230 ALOGE("startReverseTethering, execv failed (%s)", strerror(errno)); 231 } 232 ALOGE("startReverseTethering, Should never get here!"); 233 // TODO(BT) inform parent of the failure. 234 // Parent process need wait for child to report error status 235 // before it set mDhcpcdPid and return 0. 236 exit(-1); 237 } else { 238 mDhcpcdPid = pid; 239 ALOGD("Reverse Tethering running, pid:%d", pid); 240 } 241 return 0; 242} 243 244// TODO(BT) remove 245int TetherController::stopReverseTethering() { 246 247 if (mDhcpcdPid == 0) { 248 ALOGE("Tethering already stopped"); 249 return 0; 250 } 251 252 ALOGD("Stopping tethering services"); 253 254 kill(mDhcpcdPid, SIGTERM); 255 waitpid(mDhcpcdPid, NULL, 0); 256 mDhcpcdPid = 0; 257 ALOGD("Tethering services stopped"); 258 return 0; 259} 260bool TetherController::isTetheringStarted() { 261 return (mDaemonPid == 0 ? false : true); 262} 263 264#define MAX_CMD_SIZE 1024 265 266int TetherController::setDnsForwarders(char **servers, int numServers) { 267 int i; 268 char daemonCmd[MAX_CMD_SIZE]; 269 270 strcpy(daemonCmd, "update_dns"); 271 int cmdLen = strlen(daemonCmd); 272 273 mDnsForwarders->clear(); 274 for (i = 0; i < numServers; i++) { 275 ALOGD("setDnsForwarders(%d = '%s')", i, servers[i]); 276 277 struct in_addr a; 278 279 if (!inet_aton(servers[i], &a)) { 280 ALOGE("Failed to parse DNS server '%s'", servers[i]); 281 mDnsForwarders->clear(); 282 return -1; 283 } 284 285 cmdLen += (strlen(servers[i]) + 1); 286 if (cmdLen + 1 >= MAX_CMD_SIZE) { 287 ALOGD("Too many DNS servers listed"); 288 break; 289 } 290 291 strcat(daemonCmd, ":"); 292 strcat(daemonCmd, servers[i]); 293 mDnsForwarders->push_back(a); 294 } 295 296 if (mDaemonFd != -1) { 297 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 298 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 299 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 300 mDnsForwarders->clear(); 301 return -1; 302 } 303 } 304 return 0; 305} 306 307NetAddressCollection *TetherController::getDnsForwarders() { 308 return mDnsForwarders; 309} 310 311int TetherController::tetherInterface(const char *interface) { 312 mInterfaces->push_back(strdup(interface)); 313 return 0; 314} 315 316int TetherController::untetherInterface(const char *interface) { 317 InterfaceCollection::iterator it; 318 319 for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) { 320 if (!strcmp(interface, *it)) { 321 free(*it); 322 mInterfaces->erase(it); 323 return 0; 324 } 325 } 326 errno = ENOENT; 327 return -1; 328} 329 330InterfaceCollection *TetherController::getTetheredInterfaceList() { 331 return mInterfaces; 332} 333