PppController.cpp revision 1881762f345d011d079ee318d31f0a8d8ee5891e
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,
53d5573d34c8fac49e16b20cf144486125bf940086San Mehat                              struct in_addr remote) {
54d5573d34c8fac49e16b20cf144486125bf940086San Mehat    pid_t pid;
55d5573d34c8fac49e16b20cf144486125bf940086San Mehat
56d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (mPid) {
57d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("Multiple PPPD instances not currently supported");
58d5573d34c8fac49e16b20cf144486125bf940086San Mehat        errno = EBUSY;
59d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return -1;
60d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
61d5573d34c8fac49e16b20cf144486125bf940086San Mehat
621881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    TtyCollection::iterator it;
631881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
641881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        if (!strcmp(tty, *it)) {
651881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat            break;
661881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        }
671881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
681881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    if (it == mTtys->end()) {
691881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        LOGE("Invalid tty '%s' specified", tty);
701881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        errno = -EINVAL;
711881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        return -1;
721881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
731881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
74d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if ((pid = fork()) < 0) {
75d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("fork failed (%s)", strerror(errno));
76d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return -1;
77d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
78d5573d34c8fac49e16b20cf144486125bf940086San Mehat
79d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (!pid) {
80d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char *l = strdup(inet_ntoa(local));
81d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char *r = strdup(inet_ntoa(remote));
82d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char dev[32];
83d5573d34c8fac49e16b20cf144486125bf940086San Mehat        char *lr;
84d5573d34c8fac49e16b20cf144486125bf940086San Mehat
85d5573d34c8fac49e16b20cf144486125bf940086San Mehat        asprintf(&lr, "%s:%s", l, r);
86d5573d34c8fac49e16b20cf144486125bf940086San Mehat
871881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        snprintf(dev, sizeof(dev), "/dev/%s", tty);
88d5573d34c8fac49e16b20cf144486125bf940086San Mehat
89d5573d34c8fac49e16b20cf144486125bf940086San Mehat        // TODO: Deal with pppd bailing out after 99999 seconds of being started
90d5573d34c8fac49e16b20cf144486125bf940086San Mehat        // but not getting a connection
91d5573d34c8fac49e16b20cf144486125bf940086San Mehat        if (execl("/system/bin/pppd", "/system/bin/pppd", "-detach", dev,
92d5573d34c8fac49e16b20cf144486125bf940086San Mehat                  "115200", lr, "debug", "lcp-max-configure", "99999", (char *) NULL)) {
93d5573d34c8fac49e16b20cf144486125bf940086San Mehat            LOGE("execl failed (%s)", strerror(errno));
94d5573d34c8fac49e16b20cf144486125bf940086San Mehat        }
95d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("Should never get here!");
96d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
97d5573d34c8fac49e16b20cf144486125bf940086San Mehat    } else {
98d5573d34c8fac49e16b20cf144486125bf940086San Mehat        mPid = pid;
99d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
100d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
101d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
102d5573d34c8fac49e16b20cf144486125bf940086San Mehat
103d5573d34c8fac49e16b20cf144486125bf940086San Mehatint PppController::detachPppd(const char *tty) {
104d5573d34c8fac49e16b20cf144486125bf940086San Mehat
105d5573d34c8fac49e16b20cf144486125bf940086San Mehat    if (mPid == 0) {
106d5573d34c8fac49e16b20cf144486125bf940086San Mehat        LOGE("PPPD already stopped");
107d5573d34c8fac49e16b20cf144486125bf940086San Mehat        return 0;
108d5573d34c8fac49e16b20cf144486125bf940086San Mehat    }
109d5573d34c8fac49e16b20cf144486125bf940086San Mehat
110d5573d34c8fac49e16b20cf144486125bf940086San Mehat    LOGD("Stopping PPPD services on port %s", tty);
111d5573d34c8fac49e16b20cf144486125bf940086San Mehat    kill(mPid, SIGTERM);
1121881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    waitpid(mPid, NULL, 0);
113d5573d34c8fac49e16b20cf144486125bf940086San Mehat    mPid = 0;
1141881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    LOGD("PPPD services on port %s stopped", tty);
115d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return 0;
116d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
117d5573d34c8fac49e16b20cf144486125bf940086San Mehat
118d5573d34c8fac49e16b20cf144486125bf940086San MehatTtyCollection *PppController::getTtyList() {
1191881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    updateTtyList();
120d5573d34c8fac49e16b20cf144486125bf940086San Mehat    return mTtys;
121d5573d34c8fac49e16b20cf144486125bf940086San Mehat}
122d5573d34c8fac49e16b20cf144486125bf940086San Mehat
1231881762f345d011d079ee318d31f0a8d8ee5891eSan Mehatint PppController::updateTtyList() {
1241881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    TtyCollection::iterator it;
1251881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
1261881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
1271881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        free(*it);
1281881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
1291881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    mTtys->clear();
1301881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
1311881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    DIR *d = opendir("/sys/class/tty");
1321881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    if (!d) {
1331881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        LOGE("Error opening /sys/class/tty (%s)", strerror(errno));
1341881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        return -1;
1351881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
1361881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
1371881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    struct dirent *de;
1381881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    while ((de = readdir(d))) {
1391881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        if (de->d_name[0] == '.')
1401881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat            continue;
1411881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        if ((!strncmp(de->d_name, "tty", 3)) && (strlen(de->d_name) > 3)) {
1421881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat            mTtys->push_back(strdup(de->d_name));
1431881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat        }
1441881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    }
1451881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    closedir(d);
1461881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat    return 0;
1471881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat}
1481881762f345d011d079ee318d31f0a8d8ee5891eSan Mehat
149