CommandListener.cpp revision 1bdac9e98c1ef37ba568b6cf23bfbc09cfe6bf15
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; 35PppController *CommandListener::sPppCtrl = NULL; 36PanController *CommandListener::sPanCtrl = NULL; 37 38CommandListener::CommandListener() : 39 FrameworkListener("netd") { 40 registerCmd(new ListInterfacesCmd()); 41 registerCmd(new IpFwdCmd()); 42 registerCmd(new TetherCmd()); 43 registerCmd(new NatCmd()); 44 registerCmd(new ListTtysCmd()); 45 registerCmd(new PppdCmd()); 46 registerCmd(new PanCmd()); 47 48 if (!sTetherCtrl) 49 sTetherCtrl = new TetherController(); 50 if (!sNatCtrl) 51 sNatCtrl = new NatController(); 52 if (!sPppCtrl) 53 sPppCtrl = new PppController(); 54 if (!sPanCtrl) 55 sPanCtrl = new PanController(); 56} 57 58CommandListener::ListInterfacesCmd::ListInterfacesCmd() : 59 NetdCommand("list_interfaces") { 60} 61 62int CommandListener::ListInterfacesCmd::runCommand(SocketClient *cli, 63 int argc, char **argv) { 64 // XXX: Send a series of InterfaceListResults 65 cli->sendMsg(ResponseCode::CommandOkay, "Interfaces listed.", false); 66 return 0; 67} 68 69CommandListener::ListTtysCmd::ListTtysCmd() : 70 NetdCommand("list_ttys") { 71} 72 73int CommandListener::ListTtysCmd::runCommand(SocketClient *cli, 74 int argc, char **argv) { 75 TtyCollection *tlist = sPppCtrl->getTtyList(); 76 TtyCollection::iterator it; 77 78 for (it = tlist->begin(); it != tlist->end(); ++it) { 79 cli->sendMsg(ResponseCode::TtyListResult, *it, false); 80 } 81 82 cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false); 83 return 0; 84} 85 86CommandListener::IpFwdCmd::IpFwdCmd() : 87 NetdCommand("ipfwd") { 88} 89 90int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 91 int argc, char **argv) { 92 int rc = 0; 93 94 if (argc < 2) { 95 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 96 return 0; 97 } 98 99 if (!strcmp(argv[1], "status")) { 100 char *tmp = NULL; 101 102 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 103 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 104 free(tmp); 105 return 0; 106 } else if (!strcmp(argv[1], "enable")) { 107 rc = sTetherCtrl->setIpFwdEnabled(true); 108 } else if (!strcmp(argv[1], "disable")) { 109 rc = sTetherCtrl->setIpFwdEnabled(false); 110 } else { 111 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 112 return 0; 113 } 114 115 if (!rc) { 116 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 117 } else { 118 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 119 } 120 121 return 0; 122} 123 124CommandListener::TetherCmd::TetherCmd() : 125 NetdCommand("tether") { 126} 127 128int CommandListener::TetherCmd::runCommand(SocketClient *cli, 129 int argc, char **argv) { 130 int rc = 0; 131 132 if (argc < 2) { 133 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 134 return 0; 135 } 136 137 if (!strcmp(argv[1], "stop")) { 138 rc = sTetherCtrl->stopTethering(); 139 } else if (!strcmp(argv[1], "status")) { 140 char *tmp = NULL; 141 142 asprintf(&tmp, "Tethering services %s", 143 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 144 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 145 free(tmp); 146 return 0; 147 } else { 148 /* 149 * These commands take a minimum of 4 arguments 150 */ 151 if (argc < 4) { 152 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 153 return 0; 154 } 155 156 if (!strcmp(argv[1], "start")) { 157 struct in_addr s, e; 158 159 if (!inet_aton(argv[2], &s)) { 160 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid start address", false); 161 return 0; 162 } 163 if (!inet_aton(argv[3], &e)) { 164 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid end address", false); 165 return 0; 166 } 167 rc = sTetherCtrl->startTethering(s, e); 168 } else if (!strcmp(argv[1], "interface")) { 169 if (!strcmp(argv[2], "add")) { 170 rc = sTetherCtrl->tetherInterface(argv[3]); 171 } else if (!strcmp(argv[2], "remove")) { 172 rc = sTetherCtrl->untetherInterface(argv[3]); 173 } else if (!strcmp(argv[2], "list")) { 174 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 175 InterfaceCollection::iterator it; 176 177 for (it = ilist->begin(); it != ilist->end(); ++it) { 178 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 179 } 180 } else { 181 cli->sendMsg(ResponseCode::CommandParameterError, 182 "Unknown tether interface operation", false); 183 return 0; 184 } 185 } else if (!strcmp(argv[1], "dns")) { 186 if (!strcmp(argv[2], "set")) { 187 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 188 } else if (!strcmp(argv[2], "list")) { 189 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 190 NetAddressCollection::iterator it; 191 192 for (it = dlist->begin(); it != dlist->end(); ++it) { 193 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 194 } 195 } else { 196 cli->sendMsg(ResponseCode::CommandParameterError, 197 "Unknown tether interface operation", false); 198 return 0; 199 } 200 } else { 201 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 202 return 0; 203 } 204 } 205 206 if (!rc) { 207 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 208 } else { 209 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 210 } 211 212 return 0; 213} 214 215CommandListener::NatCmd::NatCmd() : 216 NetdCommand("nat") { 217} 218 219int CommandListener::NatCmd::runCommand(SocketClient *cli, 220 int argc, char **argv) { 221 int rc = 0; 222 223 if (argc < 3) { 224 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 225 return 0; 226 } 227 228 if (!strcmp(argv[1], "enable")) { 229 rc = sNatCtrl->enableNat(argv[2], argv[3]); 230 } else if (!strcmp(argv[1], "disable")) { 231 rc = sNatCtrl->disableNat(argv[2], argv[3]); 232 } else { 233 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 234 return 0; 235 } 236 237 if (!rc) { 238 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 239 } else { 240 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 241 } 242 243 return 0; 244} 245 246CommandListener::PppdCmd::PppdCmd() : 247 NetdCommand("pppd") { 248} 249 250int CommandListener::PppdCmd::runCommand(SocketClient *cli, 251 int argc, char **argv) { 252 int rc = 0; 253 254 if (argc < 3) { 255 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 256 return 0; 257 } 258 259 if (!strcmp(argv[1], "attach")) { 260 struct in_addr l, r; 261 262 if (!inet_aton(argv[3], &l)) { 263 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false); 264 return 0; 265 } 266 if (!inet_aton(argv[4], &r)) { 267 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false); 268 return 0; 269 } 270 rc = sPppCtrl->attachPppd(argv[2], l, r); 271 } else if (!strcmp(argv[1], "detach")) { 272 rc = sPppCtrl->detachPppd(argv[2]); 273 } else { 274 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false); 275 return 0; 276 } 277 278 if (!rc) { 279 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false); 280 } else { 281 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true); 282 } 283 284 return 0; 285} 286 287CommandListener::PanCmd::PanCmd() : 288 NetdCommand("pan") { 289} 290 291int CommandListener::PanCmd::runCommand(SocketClient *cli, 292 int argc, char **argv) { 293 int rc = 0; 294 295 if (argc < 2) { 296 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 297 return 0; 298 } 299 300 if (!strcmp(argv[1], "start")) { 301 rc = sPanCtrl->startPan(); 302 } else if (!strcmp(argv[1], "stop")) { 303 rc = sPanCtrl->stopPan(); 304 } else if (!strcmp(argv[1], "status")) { 305 char *tmp = NULL; 306 307 asprintf(&tmp, "Pan services %s", 308 (sPanCtrl->isPanStarted() ? "started" : "stopped")); 309 cli->sendMsg(ResponseCode::PanStatusResult, tmp, false); 310 free(tmp); 311 return 0; 312 } else { 313 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pan cmd", false); 314 return 0; 315 } 316 317 if (!rc) { 318 cli->sendMsg(ResponseCode::CommandOkay, "Pan operation succeeded", false); 319 } else { 320 cli->sendMsg(ResponseCode::OperationFailed, "Pan operation failed", true); 321 } 322 323 return 0; 324} 325