CommandListener.cpp revision 9ff78fb7da7158f5bd7c86d89a842691820259cf
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdlib.h> 18#include <sys/socket.h> 19#include <sys/types.h> 20#include <netinet/in.h> 21#include <arpa/inet.h> 22#include <dirent.h> 23#include <errno.h> 24 25#define LOG_TAG "CommandListener" 26#include <cutils/log.h> 27 28#include <sysutils/SocketClient.h> 29 30#include "CommandListener.h" 31#include "ResponseCode.h" 32 33TetherController *CommandListener::sTetherCtrl = NULL; 34NatController *CommandListener::sNatCtrl = NULL; 35 36CommandListener::CommandListener() : 37 FrameworkListener("netd") { 38 registerCmd(new ListInterfacesCmd()); 39 registerCmd(new IpFwdCmd()); 40 registerCmd(new TetherCmd()); 41 registerCmd(new NatCmd()); 42 43 if (!sTetherCtrl) 44 sTetherCtrl = new TetherController(); 45 if (!sNatCtrl) 46 sNatCtrl = new NatController(); 47} 48 49CommandListener::ListInterfacesCmd::ListInterfacesCmd() : 50 NetdCommand("list_interfaces") { 51} 52 53int CommandListener::ListInterfacesCmd::runCommand(SocketClient *cli, 54 int argc, char **argv) { 55 // XXX: Send a series of InterfaceListResults 56 cli->sendMsg(ResponseCode::CommandOkay, "Interfaces listed.", false); 57 return 0; 58} 59 60CommandListener::IpFwdCmd::IpFwdCmd() : 61 NetdCommand("ipfwd") { 62} 63 64int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 65 int argc, char **argv) { 66 int rc = 0; 67 68 if (argc < 2) { 69 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 70 return 0; 71 } 72 73 if (!strcmp(argv[1], "status")) { 74 char *tmp = NULL; 75 76 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 77 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 78 free(tmp); 79 return 0; 80 } else if (!strcmp(argv[1], "enable")) { 81 rc = sTetherCtrl->setIpFwdEnabled(true); 82 } else if (!strcmp(argv[1], "disable")) { 83 rc = sTetherCtrl->setIpFwdEnabled(false); 84 } else { 85 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 86 return 0; 87 } 88 89 if (!rc) { 90 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 91 } else { 92 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 93 } 94 95 return 0; 96} 97 98CommandListener::TetherCmd::TetherCmd() : 99 NetdCommand("tether") { 100} 101 102int CommandListener::TetherCmd::runCommand(SocketClient *cli, 103 int argc, char **argv) { 104 int rc = 0; 105 106 if (argc < 2) { 107 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 108 return 0; 109 } 110 111 if (!strcmp(argv[1], "stop")) { 112 rc = sTetherCtrl->stopTethering(); 113 } else if (!strcmp(argv[1], "status")) { 114 char *tmp = NULL; 115 116 asprintf(&tmp, "Tethering services %s", 117 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 118 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 119 free(tmp); 120 return 0; 121 } else { 122 /* 123 * These commands take a minimum of 4 arguments 124 */ 125 if (argc < 4) { 126 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 127 return 0; 128 } 129 130 if (!strcmp(argv[1], "start")) { 131 struct in_addr s, e; 132 133 if (!inet_aton(argv[2], &s)) { 134 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid start address", false); 135 return 0; 136 } 137 if (!inet_aton(argv[3], &e)) { 138 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid end address", false); 139 return 0; 140 } 141 rc = sTetherCtrl->startTethering(s, e); 142 } else if (!strcmp(argv[1], "interface")) { 143 if (!strcmp(argv[2], "add")) { 144 rc = sTetherCtrl->tetherInterface(argv[3]); 145 } else if (!strcmp(argv[2], "remove")) { 146 rc = sTetherCtrl->untetherInterface(argv[3]); 147 } else if (!strcmp(argv[2], "list")) { 148 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 149 InterfaceCollection::iterator it; 150 151 for (it = ilist->begin(); it != ilist->end(); ++it) { 152 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 153 } 154 } else { 155 cli->sendMsg(ResponseCode::CommandParameterError, 156 "Unknown tether interface operation", false); 157 return 0; 158 } 159 } else if (!strcmp(argv[1], "dns")) { 160 if (!strcmp(argv[2], "set")) { 161 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 162 } else if (!strcmp(argv[2], "list")) { 163 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 164 NetAddressCollection::iterator it; 165 166 for (it = dlist->begin(); it != dlist->end(); ++it) { 167 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 168 } 169 } else { 170 cli->sendMsg(ResponseCode::CommandParameterError, 171 "Unknown tether interface operation", false); 172 return 0; 173 } 174 } else { 175 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 176 return 0; 177 } 178 } 179 180 if (!rc) { 181 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 182 } else { 183 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 184 } 185 186 return 0; 187} 188 189CommandListener::NatCmd::NatCmd() : 190 NetdCommand("nat") { 191} 192 193int CommandListener::NatCmd::runCommand(SocketClient *cli, 194 int argc, char **argv) { 195 int rc = 0; 196 197 if (argc < 3) { 198 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 199 return 0; 200 } 201 202 if (!strcmp(argv[1], "enable")) { 203 rc = sNatCtrl->enableNat(argv[2], argv[3]); 204 } else if (!strcmp(argv[1], "disable")) { 205 rc = sNatCtrl->disableNat(argv[2], argv[3]); 206 } else { 207 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 208 return 0; 209 } 210 211 if (!rc) { 212 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 213 } else { 214 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 215 } 216 217 return 0; 218} 219 220