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