CommandListener.cpp revision 9ff78fb7da7158f5bd7c86d89a842691820259cf
1d18304287dbabc7835be771400b85d4ae8b63de6San Mehat/*
2d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Copyright (C) 2008 The Android Open Source Project
3d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *
4d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * you may not use this file except in compliance with the License.
6d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * You may obtain a copy of the License at
7d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *
8d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9d18304287dbabc7835be771400b85d4ae8b63de6San Mehat *
10d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * Unless required by applicable law or agreed to in writing, software
11d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * See the License for the specific language governing permissions and
14d18304287dbabc7835be771400b85d4ae8b63de6San Mehat * limitations under the License.
15d18304287dbabc7835be771400b85d4ae8b63de6San Mehat */
16d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
17d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <stdlib.h>
18d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/socket.h>
19d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sys/types.h>
20d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <netinet/in.h>
21d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <arpa/inet.h>
22d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <dirent.h>
23d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <errno.h>
24d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
25d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#define LOG_TAG "CommandListener"
26d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <cutils/log.h>
27d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
28d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include <sysutils/SocketClient.h>
29d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
30d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "CommandListener.h"
31d18304287dbabc7835be771400b85d4ae8b63de6San Mehat#include "ResponseCode.h"
32d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
339d10b341a0ba46f108cb96e46691197d778cbc06San MehatTetherController *CommandListener::sTetherCtrl = NULL;
349ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController *CommandListener::sNatCtrl = NULL;
359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
36d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::CommandListener() :
37d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 FrameworkListener("netd") {
38d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new ListInterfacesCmd());
39d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new IpFwdCmd());
40d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new TetherCmd());
41d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    registerCmd(new NatCmd());
429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!sTetherCtrl)
449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        sTetherCtrl = new TetherController();
459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    if (!sNatCtrl)
469ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat        sNatCtrl = new NatController();
47d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
48d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
49d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::ListInterfacesCmd::ListInterfacesCmd() :
50d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("list_interfaces") {
51d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
52d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
53d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::ListInterfacesCmd::runCommand(SocketClient *cli,
54d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    // XXX: Send a series of InterfaceListResults
56d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    cli->sendMsg(ResponseCode::CommandOkay, "Interfaces listed.", false);
57d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
58d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
59d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
60d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::IpFwdCmd::IpFwdCmd() :
61d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("ipfwd") {
62d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
63d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
64d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::IpFwdCmd::runCommand(SocketClient *cli,
65d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (argc < 2) {
699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!strcmp(argv[1], "status")) {
749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *tmp = NULL;
759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled"));
779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(tmp);
799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else if (!strcmp(argv[1], "enable")) {
819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->setIpFwdEnabled(true);
829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else if (!strcmp(argv[1], "disable")) {
839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->setIpFwdEnabled(false);
849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
919d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
94d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
95d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
96d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
97d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
98d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::TetherCmd::TetherCmd() :
99d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("tether") {
100d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
101d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
102d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::TetherCmd::runCommand(SocketClient *cli,
103d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
1049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
1059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
106d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    if (argc < 2) {
107d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
108d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        return 0;
109d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    }
110d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
1119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!strcmp(argv[1], "stop")) {
1129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        rc = sTetherCtrl->stopTethering();
113d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    } else if (!strcmp(argv[1], "status")) {
1149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        char *tmp = NULL;
1159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        asprintf(&tmp, "Tethering services %s",
1179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped"));
1189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false);
1199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        free(tmp);
120d18304287dbabc7835be771400b85d4ae8b63de6San Mehat        return 0;
1219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
1229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        /*
1239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat         * These commands take a minimum of 4 arguments
1249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat         */
1259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (argc < 4) {
1269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
1289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        if (!strcmp(argv[1], "start")) {
1319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            struct in_addr s, e;
1329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!inet_aton(argv[2], &s)) {
1349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError, "Invalid start address", false);
1359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
1369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!inet_aton(argv[3], &e)) {
1389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError, "Invalid end address", false);
1399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
1409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            rc = sTetherCtrl->startTethering(s, e);
1429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else if (!strcmp(argv[1], "interface")) {
1439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!strcmp(argv[2], "add")) {
1449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->tetherInterface(argv[3]);
1459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else if (!strcmp(argv[2], "remove")) {
1469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->untetherInterface(argv[3]);
1479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else if (!strcmp(argv[2], "list")) {
1489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList();
1499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                InterfaceCollection::iterator it;
1509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                for (it = ilist->begin(); it != ilist->end(); ++it) {
1529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                    cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
1539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                }
1549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else {
1559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError,
1569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                             "Unknown tether interface operation", false);
1579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
1589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else if (!strcmp(argv[1], "dns")) {
1609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            if (!strcmp(argv[2], "set")) {
1619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3);
1629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else if (!strcmp(argv[2], "list")) {
1639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders();
1649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                NetAddressCollection::iterator it;
1659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                for (it = dlist->begin(); it != dlist->end(); ++it) {
1679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                    cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false);
1689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                }
1699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            } else {
1709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                cli->sendMsg(ResponseCode::CommandParameterError,
1719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                             "Unknown tether interface operation", false);
1729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat                return 0;
1739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            }
1749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        } else {
1759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false);
1769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat            return 0;
1779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        }
1789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
1799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
1819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false);
1829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
1839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true);
184d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    }
185d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
186d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
187d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
188d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
189d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::NatCmd::NatCmd() :
190d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                 NetdCommand("nat") {
191d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
192d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
193d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::NatCmd::runCommand(SocketClient *cli,
194d18304287dbabc7835be771400b85d4ae8b63de6San Mehat                                                      int argc, char **argv) {
1959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    int rc = 0;
1969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
1979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (argc < 3) {
1989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
1999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
2009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2029ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    if (!strcmp(argv[1], "enable")) {
2039ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat        rc = sNatCtrl->enableNat(argv[2], argv[3]);
2049ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat    } else if (!strcmp(argv[1], "disable")) {
2059ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat        rc = sNatCtrl->disableNat(argv[2], argv[3]);
2069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
2079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false);
2089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        return 0;
2099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
2109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat
2119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    if (!rc) {
2129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false);
2139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    } else {
2149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat        cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true);
2159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat    }
216d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
217d18304287dbabc7835be771400b85d4ae8b63de6San Mehat    return 0;
218d18304287dbabc7835be771400b85d4ae8b63de6San Mehat}
219d18304287dbabc7835be771400b85d4ae8b63de6San Mehat
220