CommandListener.cpp revision 9d10b341a0ba46f108cb96e46691197d778cbc06
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; 349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 35d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::CommandListener() : 36d18304287dbabc7835be771400b85d4ae8b63de6San Mehat FrameworkListener("netd") { 37d18304287dbabc7835be771400b85d4ae8b63de6San Mehat registerCmd(new ListInterfacesCmd()); 38d18304287dbabc7835be771400b85d4ae8b63de6San Mehat registerCmd(new IpFwdCmd()); 39d18304287dbabc7835be771400b85d4ae8b63de6San Mehat registerCmd(new TetherCmd()); 40d18304287dbabc7835be771400b85d4ae8b63de6San Mehat registerCmd(new NatCmd()); 419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!sTetherCtrl) 439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat sTetherCtrl = new TetherController(); 44d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 45d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 46d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::ListInterfacesCmd::ListInterfacesCmd() : 47d18304287dbabc7835be771400b85d4ae8b63de6San Mehat NetdCommand("list_interfaces") { 48d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 49d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 50d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::ListInterfacesCmd::runCommand(SocketClient *cli, 51d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int argc, char **argv) { 529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat // XXX: Send a series of InterfaceListResults 53d18304287dbabc7835be771400b85d4ae8b63de6San Mehat cli->sendMsg(ResponseCode::CommandOkay, "Interfaces listed.", false); 54d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 55d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 56d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 57d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::IpFwdCmd::IpFwdCmd() : 58d18304287dbabc7835be771400b85d4ae8b63de6San Mehat NetdCommand("ipfwd") { 59d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 60d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 61d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 62d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int argc, char **argv) { 639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat int rc = 0; 649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (argc < 2) { 669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!strcmp(argv[1], "status")) { 719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat char *tmp = NULL; 729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat free(tmp); 769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[1], "enable")) { 789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = sTetherCtrl->setIpFwdEnabled(true); 799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[1], "disable")) { 809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = sTetherCtrl->setIpFwdEnabled(false); 819d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 829d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 839d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 849d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 859d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 869d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!rc) { 879d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 889d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 899d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 909d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 91d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 92d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 93d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 94d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 95d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::TetherCmd::TetherCmd() : 96d18304287dbabc7835be771400b85d4ae8b63de6San Mehat NetdCommand("tether") { 97d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 98d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 99d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::TetherCmd::runCommand(SocketClient *cli, 100d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int argc, char **argv) { 1019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat int rc = 0; 1029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 103d18304287dbabc7835be771400b85d4ae8b63de6San Mehat if (argc < 2) { 104d18304287dbabc7835be771400b85d4ae8b63de6San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 105d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 106d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 107d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 1089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!strcmp(argv[1], "stop")) { 1099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = sTetherCtrl->stopTethering(); 110d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } else if (!strcmp(argv[1], "status")) { 1119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat char *tmp = NULL; 1129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat asprintf(&tmp, "Tethering services %s", 1149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 1159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 1169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat free(tmp); 117d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 1189d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 1199d10b341a0ba46f108cb96e46691197d778cbc06San Mehat /* 1209d10b341a0ba46f108cb96e46691197d778cbc06San Mehat * These commands take a minimum of 4 arguments 1219d10b341a0ba46f108cb96e46691197d778cbc06San Mehat */ 1229d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (argc < 4) { 1239d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1249d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 1259d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1269d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1279d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!strcmp(argv[1], "start")) { 1289d10b341a0ba46f108cb96e46691197d778cbc06San Mehat struct in_addr s, e; 1299d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1309d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!inet_aton(argv[2], &s)) { 1319d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandParameterError, "Invalid start address", false); 1329d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 1339d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1349d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!inet_aton(argv[3], &e)) { 1359d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandParameterError, "Invalid end address", false); 1369d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 1379d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1389d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = sTetherCtrl->startTethering(s, e); 1399d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[1], "interface")) { 1409d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!strcmp(argv[2], "add")) { 1419d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = sTetherCtrl->tetherInterface(argv[3]); 1429d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[2], "remove")) { 1439d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = sTetherCtrl->untetherInterface(argv[3]); 1449d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[2], "list")) { 1459d10b341a0ba46f108cb96e46691197d778cbc06San Mehat InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 1469d10b341a0ba46f108cb96e46691197d778cbc06San Mehat InterfaceCollection::iterator it; 1479d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1489d10b341a0ba46f108cb96e46691197d778cbc06San Mehat for (it = ilist->begin(); it != ilist->end(); ++it) { 1499d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 1509d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1519d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 1529d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandParameterError, 1539d10b341a0ba46f108cb96e46691197d778cbc06San Mehat "Unknown tether interface operation", false); 1549d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 1559d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1569d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[1], "dns")) { 1579d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!strcmp(argv[2], "set")) { 1589d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 1599d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[2], "list")) { 1609d10b341a0ba46f108cb96e46691197d778cbc06San Mehat NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 1619d10b341a0ba46f108cb96e46691197d778cbc06San Mehat NetAddressCollection::iterator it; 1629d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1639d10b341a0ba46f108cb96e46691197d778cbc06San Mehat for (it = dlist->begin(); it != dlist->end(); ++it) { 1649d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 1659d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1669d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 1679d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandParameterError, 1689d10b341a0ba46f108cb96e46691197d778cbc06San Mehat "Unknown tether interface operation", false); 1699d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 1709d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1719d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 1729d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 1739d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 1749d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1759d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1769d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1779d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!rc) { 1789d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 1799d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 1809d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 181d18304287dbabc7835be771400b85d4ae8b63de6San Mehat } 182d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 183d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 184d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 185d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 186d18304287dbabc7835be771400b85d4ae8b63de6San MehatCommandListener::NatCmd::NatCmd() : 187d18304287dbabc7835be771400b85d4ae8b63de6San Mehat NetdCommand("nat") { 188d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 189d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 190d18304287dbabc7835be771400b85d4ae8b63de6San Mehatint CommandListener::NatCmd::runCommand(SocketClient *cli, 191d18304287dbabc7835be771400b85d4ae8b63de6San Mehat int argc, char **argv) { 1929d10b341a0ba46f108cb96e46691197d778cbc06San Mehat int rc = 0; 1939d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1949d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (argc < 3) { 1959d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1969d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 1979d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 1989d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 1999d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!strcmp(argv[1], "binding")) { 2009d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!strcmp(argv[2], "add")) { 2019d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = 0; 2029d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else if (!strcmp(argv[2], "remove")) { 2039d10b341a0ba46f108cb96e46691197d778cbc06San Mehat rc = 0; 2049d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 2059d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat binding cmd", false); 2069d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 2079d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 2089d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 2099d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 2109d10b341a0ba46f108cb96e46691197d778cbc06San Mehat return 0; 2119d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 2129d10b341a0ba46f108cb96e46691197d778cbc06San Mehat 2139d10b341a0ba46f108cb96e46691197d778cbc06San Mehat if (!rc) { 2149d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 2159d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } else { 2169d10b341a0ba46f108cb96e46691197d778cbc06San Mehat cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 2179d10b341a0ba46f108cb96e46691197d778cbc06San Mehat } 218d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 219d18304287dbabc7835be771400b85d4ae8b63de6San Mehat return 0; 220d18304287dbabc7835be771400b85d4ae8b63de6San Mehat} 221d18304287dbabc7835be771400b85d4ae8b63de6San Mehat 222