CommandListener.cpp revision 9d10b341a0ba46f108cb96e46691197d778cbc06
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; 34 35CommandListener::CommandListener() : 36 FrameworkListener("netd") { 37 registerCmd(new ListInterfacesCmd()); 38 registerCmd(new IpFwdCmd()); 39 registerCmd(new TetherCmd()); 40 registerCmd(new NatCmd()); 41 42 if (!sTetherCtrl) 43 sTetherCtrl = new TetherController(); 44} 45 46CommandListener::ListInterfacesCmd::ListInterfacesCmd() : 47 NetdCommand("list_interfaces") { 48} 49 50int CommandListener::ListInterfacesCmd::runCommand(SocketClient *cli, 51 int argc, char **argv) { 52 // XXX: Send a series of InterfaceListResults 53 cli->sendMsg(ResponseCode::CommandOkay, "Interfaces listed.", false); 54 return 0; 55} 56 57CommandListener::IpFwdCmd::IpFwdCmd() : 58 NetdCommand("ipfwd") { 59} 60 61int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 62 int argc, char **argv) { 63 int rc = 0; 64 65 if (argc < 2) { 66 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 67 return 0; 68 } 69 70 if (!strcmp(argv[1], "status")) { 71 char *tmp = NULL; 72 73 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 74 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 75 free(tmp); 76 return 0; 77 } else if (!strcmp(argv[1], "enable")) { 78 rc = sTetherCtrl->setIpFwdEnabled(true); 79 } else if (!strcmp(argv[1], "disable")) { 80 rc = sTetherCtrl->setIpFwdEnabled(false); 81 } else { 82 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 83 return 0; 84 } 85 86 if (!rc) { 87 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 88 } else { 89 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 90 } 91 92 return 0; 93} 94 95CommandListener::TetherCmd::TetherCmd() : 96 NetdCommand("tether") { 97} 98 99int CommandListener::TetherCmd::runCommand(SocketClient *cli, 100 int argc, char **argv) { 101 int rc = 0; 102 103 if (argc < 2) { 104 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 105 return 0; 106 } 107 108 if (!strcmp(argv[1], "stop")) { 109 rc = sTetherCtrl->stopTethering(); 110 } else if (!strcmp(argv[1], "status")) { 111 char *tmp = NULL; 112 113 asprintf(&tmp, "Tethering services %s", 114 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 115 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 116 free(tmp); 117 return 0; 118 } else { 119 /* 120 * These commands take a minimum of 4 arguments 121 */ 122 if (argc < 4) { 123 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 124 return 0; 125 } 126 127 if (!strcmp(argv[1], "start")) { 128 struct in_addr s, e; 129 130 if (!inet_aton(argv[2], &s)) { 131 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid start address", false); 132 return 0; 133 } 134 if (!inet_aton(argv[3], &e)) { 135 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid end address", false); 136 return 0; 137 } 138 rc = sTetherCtrl->startTethering(s, e); 139 } else if (!strcmp(argv[1], "interface")) { 140 if (!strcmp(argv[2], "add")) { 141 rc = sTetherCtrl->tetherInterface(argv[3]); 142 } else if (!strcmp(argv[2], "remove")) { 143 rc = sTetherCtrl->untetherInterface(argv[3]); 144 } else if (!strcmp(argv[2], "list")) { 145 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 146 InterfaceCollection::iterator it; 147 148 for (it = ilist->begin(); it != ilist->end(); ++it) { 149 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 150 } 151 } else { 152 cli->sendMsg(ResponseCode::CommandParameterError, 153 "Unknown tether interface operation", false); 154 return 0; 155 } 156 } else if (!strcmp(argv[1], "dns")) { 157 if (!strcmp(argv[2], "set")) { 158 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 159 } else if (!strcmp(argv[2], "list")) { 160 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 161 NetAddressCollection::iterator it; 162 163 for (it = dlist->begin(); it != dlist->end(); ++it) { 164 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 165 } 166 } else { 167 cli->sendMsg(ResponseCode::CommandParameterError, 168 "Unknown tether interface operation", false); 169 return 0; 170 } 171 } else { 172 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 173 return 0; 174 } 175 } 176 177 if (!rc) { 178 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 179 } else { 180 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 181 } 182 183 return 0; 184} 185 186CommandListener::NatCmd::NatCmd() : 187 NetdCommand("nat") { 188} 189 190int CommandListener::NatCmd::runCommand(SocketClient *cli, 191 int argc, char **argv) { 192 int rc = 0; 193 194 if (argc < 3) { 195 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 196 return 0; 197 } 198 199 if (!strcmp(argv[1], "binding")) { 200 if (!strcmp(argv[2], "add")) { 201 rc = 0; 202 } else if (!strcmp(argv[2], "remove")) { 203 rc = 0; 204 } else { 205 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat binding cmd", false); 206 return 0; 207 } 208 } else { 209 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 210 return 0; 211 } 212 213 if (!rc) { 214 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 215 } else { 216 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 217 } 218 219 return 0; 220} 221 222