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