PppController.cpp revision 74d8fdd307275bfdf95dcf61d9e6366e87da24ec
1d5573d34c8fac49e16b20cf144486125bf940086San Mehat/*
2d5573d34c8fac49e16b20cf144486125bf940086San Mehat * Copyright (C) 2008 The Android Open Source Project
3d5573d34c8fac49e16b20cf144486125bf940086San Mehat *
4d5573d34c8fac49e16b20cf144486125bf940086San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5d5573d34c8fac49e16b20cf144486125bf940086San Mehat * you may not use this file except in compliance with the License.
6d5573d34c8fac49e16b20cf144486125bf940086San Mehat * You may obtain a copy of the License at
7d5573d34c8fac49e16b20cf144486125bf940086San Mehat *
8d5573d34c8fac49e16b20cf144486125bf940086San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9d5573d34c8fac49e16b20cf144486125bf940086San Mehat *
10d5573d34c8fac49e16b20cf144486125bf940086San Mehat * Unless required by applicable law or agreed to in writing, software
11d5573d34c8fac49e16b20cf144486125bf940086San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12d5573d34c8fac49e16b20cf144486125bf940086San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d5573d34c8fac49e16b20cf144486125bf940086San Mehat * See the License for the specific language governing permissions and
14d5573d34c8fac49e16b20cf144486125bf940086San Mehat * limitations under the License.
15d5573d34c8fac49e16b20cf144486125bf940086San Mehat */
16d5573d34c8fac49e16b20cf144486125bf940086San Mehat
17d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include <stdlib.h>
18d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include <errno.h>
191881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat#include <fcntl.h>
201881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
21d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include <sys/socket.h>
22d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include <sys/stat.h>
231881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat#include <sys/types.h>
241881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat#include <sys/wait.h>
251881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
261881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat#include <dirent.h>
271881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
28d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include <netinet/in.h>
29d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include <arpa/inet.h>
30d5573d34c8fac49e16b20cf144486125bf940086San Mehat
31d5573d34c8fac49e16b20cf144486125bf940086San Mehat#define LOG_TAG "PppController"
32d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include <cutils/log.h>
33d5573d34c8fac49e16b20cf144486125bf940086San Mehat
34d5573d34c8fac49e16b20cf144486125bf940086San Mehat#include "PppController.h"
35d5573d34c8fac49e16b20cf144486125bf940086San Mehat
36d5573d34c8fac49e16b20cf144486125bf940086San Mehatextern "C" int logwrap(int argc, const char **argv, int background);
37d5573d34c8fac49e16b20cf144486125bf940086San Mehat
38d5573d34c8fac49e16b20cf144486125bf940086San MehatPppController::PppController() {
39d5573d34c8fac49e16b20cf144486125bf940086San Mehat    mTtys = new TtyCollection();
40d5573d34c8fac49e16b20cf144486125bf940086San Mehat    mPid = 0;
41d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
42d5573d34c8fac49e16b20cf144486125bf940086San Mehat
43d5573d34c8fac49e16b20cf144486125bf940086San MehatPppController::~PppController() {
44d5573d34c8fac49e16b20cf144486125bf940086San Mehat    TtyCollection::iterator it;
45d5573d34c8fac49e16b20cf144486125bf940086San Mehat
46d5573d34c8fac49e16b20cf144486125bf940086San Mehat    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
47d5573d34c8fac49e16b20cf144486125bf940086San Mehat        free(*it);
48d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
49d5573d34c8fac49e16b20cf144486125bf940086San Mehat    mTtys->clear();
50d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
51d5573d34c8fac49e16b20cf144486125bf940086San Mehat
52d5573d34c8fac49e16b20cf144486125bf940086San Mehatint PppController::attachPppd(const char *tty, struct in_addr local,
5374d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt                              struct in_addr remote, struct in_addr dns1,
5474d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt                              struct in_addr dns2) {
55d5573d34c8fac49e16b20cf144486125bf940086San Mehat    pid_t pid;
56d5573d34c8fac49e16b20cf144486125bf940086San Mehat
57d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (mPid) {
58d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("Multiple PPPD instances not currently supported");
59d5573d34c8fac49e16b20cf144486125bf940086San Mehat        errno = EBUSY;
60d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return -1;
61d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
62d5573d34c8fac49e16b20cf144486125bf940086San Mehat
631881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    TtyCollection::iterator it;
641881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
651881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        if (!strcmp(tty, *it)) {
661881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat            break;
671881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        }
681881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
691881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    if (it == mTtys->end()) {
701881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        LOGE("Invalid tty '%s' specified", tty);
711881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        errno = -EINVAL;
721881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        return -1;
731881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
741881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
75d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if ((pid = fork()) < 0) {
76d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("fork failed (%s)", strerror(errno));
77d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return -1;
78d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
79d5573d34c8fac49e16b20cf144486125bf940086San Mehat
80d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!pid) {
81d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char *l = strdup(inet_ntoa(local));
82d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char *r = strdup(inet_ntoa(remote));
8374d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        char *d1 = strdup(inet_ntoa(dns1));
8474d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        char *d2 = strdup(inet_ntoa(dns2));
85d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char dev[32];
86d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char *lr;
87d5573d34c8fac49e16b20cf144486125bf940086San Mehat
88d5573d34c8fac49e16b20cf144486125bf940086San Mehat        asprintf(&lr, "%s:%s", l, r);
89d5573d34c8fac49e16b20cf144486125bf940086San Mehat
901881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        snprintf(dev, sizeof(dev), "/dev/%s", tty);
91d5573d34c8fac49e16b20cf144486125bf940086San Mehat
92d5573d34c8fac49e16b20cf144486125bf940086San Mehat        // TODO: Deal with pppd bailing out after 99999 seconds of being started
93d5573d34c8fac49e16b20cf144486125bf940086San Mehat        // but not getting a connection
9474d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt        if (execl("/system/bin/pppd", "/system/bin/pppd", "-detach", dev, "115200",
9574d8fdd307275bfdf95dcf61d9e6366e87da24ecRobert Greenwalt                  lr, "ms-dns", d1, "ms-dns", d2, "debug", "lcp-max-configure", "99999", (char *) NULL)) {
96d5573d34c8fac49e16b20cf144486125bf940086San Mehat            LOGE("execl failed (%s)", strerror(errno));
97d5573d34c8fac49e16b20cf144486125bf940086San Mehat        }
98d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("Should never get here!");
99d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
100d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else {
101d5573d34c8fac49e16b20cf144486125bf940086San Mehat        mPid = pid;
102d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
103d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
104d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
105d5573d34c8fac49e16b20cf144486125bf940086San Mehat
106d5573d34c8fac49e16b20cf144486125bf940086San Mehatint PppController::detachPppd(const char *tty) {
107d5573d34c8fac49e16b20cf144486125bf940086San Mehat
108d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (mPid == 0) {
109d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("PPPD already stopped");
110d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
111d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
112d5573d34c8fac49e16b20cf144486125bf940086San Mehat
113d5573d34c8fac49e16b20cf144486125bf940086San Mehat    LOGD("Stopping PPPD services on port %s", tty);
114d5573d34c8fac49e16b20cf144486125bf940086San Mehat    kill(mPid, SIGTERM);
1151881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    waitpid(mPid, NULL, 0);
116d5573d34c8fac49e16b20cf144486125bf940086San Mehat    mPid = 0;
1171881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    LOGD("PPPD services on port %s stopped", tty);
118d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
119d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
120d5573d34c8fac49e16b20cf144486125bf940086San Mehat
121d5573d34c8fac49e16b20cf144486125bf940086San MehatTtyCollection *PppController::getTtyList() {
1221881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    updateTtyList();
123d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return mTtys;
124d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
125d5573d34c8fac49e16b20cf144486125bf940086San Mehat
1261881762f345d011d079ee318d31f0a8d8ee5891eSan Mehatint PppController::updateTtyList() {
1271881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    TtyCollection::iterator it;
1281881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
1291881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
1301881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        free(*it);
1311881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
1321881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    mTtys->clear();
1331881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
1341881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    DIR *d = opendir("/sys/class/tty");
1351881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    if (!d) {
1361881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        LOGE("Error opening /sys/class/tty (%s)", strerror(errno));
1371881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        return -1;
1381881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
1391881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
1401881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    struct dirent *de;
1411881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    while ((de = readdir(d))) {
1421881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        if (de->d_name[0] == '.')
1431881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat            continue;
1441881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        if ((!strncmp(de->d_name, "tty", 3)) && (strlen(de->d_name) > 3)) {
1451881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat            mTtys->push_back(strdup(de->d_name));
1461881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        }
1471881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
1481881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    closedir(d);
1491881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    return 0;
1501881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat}
151