Home | History | Annotate | Download | only in server
      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