CommandListener.cpp revision ab374f426a0d1d8598f3eb4b0339440dcb313a1a
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#include <string.h> 25 26#include <linux/if.h> 27 28#define LOG_TAG "CommandListener" 29#include <cutils/log.h> 30 31#include <sysutils/SocketClient.h> 32 33#include "CommandListener.h" 34#include "ResponseCode.h" 35#include "ThrottleController.h" 36#include "BandwidthController.h" 37 38 39extern "C" int ifc_init(void); 40extern "C" int ifc_close(void); 41extern "C" int ifc_get_hwaddr(const char *name, void *ptr); 42extern "C" int ifc_get_info(const char *name, in_addr_t *addr, int *prefixLength, unsigned *flags); 43extern "C" int ifc_get_addr(const char *name, in_addr_t *addr); 44extern "C" int ifc_set_addr(const char *name, in_addr_t addr); 45extern "C" int ifc_set_prefixLength(const char *name, int prefixLength); 46extern "C" int ifc_up(const char *name); 47extern "C" int ifc_down(const char *name); 48extern "C" int ifc_add_route(const char *name, const char *dst, int prefix_length, const char *gw); 49extern "C" int ifc_remove_route(const char *name, const char *dst, int p_length, const char *gw); 50 51TetherController *CommandListener::sTetherCtrl = NULL; 52NatController *CommandListener::sNatCtrl = NULL; 53PppController *CommandListener::sPppCtrl = NULL; 54PanController *CommandListener::sPanCtrl = NULL; 55SoftapController *CommandListener::sSoftapCtrl = NULL; 56BandwidthController * CommandListener::sBandwidthCtrl = NULL; 57ResolverController *CommandListener::sResolverCtrl = NULL; 58 59CommandListener::CommandListener() : 60 FrameworkListener("netd") { 61 registerCmd(new InterfaceCmd()); 62 registerCmd(new IpFwdCmd()); 63 registerCmd(new TetherCmd()); 64 registerCmd(new NatCmd()); 65 registerCmd(new ListTtysCmd()); 66 registerCmd(new PppdCmd()); 67 registerCmd(new PanCmd()); 68 registerCmd(new SoftapCmd()); 69 registerCmd(new BandwidthControlCmd()); 70 registerCmd(new ResolverCmd()); 71 72 if (!sTetherCtrl) 73 sTetherCtrl = new TetherController(); 74 if (!sNatCtrl) 75 sNatCtrl = new NatController(); 76 if (!sPppCtrl) 77 sPppCtrl = new PppController(); 78 if (!sPanCtrl) 79 sPanCtrl = new PanController(); 80 if (!sSoftapCtrl) 81 sSoftapCtrl = new SoftapController(); 82 if (!sBandwidthCtrl) 83 sBandwidthCtrl = new BandwidthController(); 84 if (!sResolverCtrl) 85 sResolverCtrl = new ResolverController(); 86} 87 88CommandListener::InterfaceCmd::InterfaceCmd() : 89 NetdCommand("interface") { 90} 91 92int CommandListener::InterfaceCmd::runCommand(SocketClient *cli, 93 int argc, char **argv) { 94 if (argc < 2) { 95 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 96 return 0; 97 } 98 99 if (!strcmp(argv[1], "list")) { 100 DIR *d; 101 struct dirent *de; 102 103 if (!(d = opendir("/sys/class/net"))) { 104 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true); 105 return 0; 106 } 107 108 while((de = readdir(d))) { 109 if (de->d_name[0] == '.') 110 continue; 111 cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false); 112 } 113 closedir(d); 114 cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false); 115 return 0; 116 } else if (!strcmp(argv[1], "readrxcounter")) { 117 if (argc != 3) { 118 cli->sendMsg(ResponseCode::CommandSyntaxError, 119 "Usage: interface readrxcounter <interface>", false); 120 return 0; 121 } 122 unsigned long rx = 0, tx = 0; 123 if (readInterfaceCounters(argv[2], &rx, &tx)) { 124 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 125 return 0; 126 } 127 128 char *msg; 129 asprintf(&msg, "%lu", rx); 130 cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false); 131 free(msg); 132 133 return 0; 134 } else if (!strcmp(argv[1], "readtxcounter")) { 135 if (argc != 3) { 136 cli->sendMsg(ResponseCode::CommandSyntaxError, 137 "Usage: interface readtxcounter <interface>", false); 138 return 0; 139 } 140 unsigned long rx = 0, tx = 0; 141 if (readInterfaceCounters(argv[2], &rx, &tx)) { 142 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 143 return 0; 144 } 145 146 char *msg = NULL; 147 asprintf(&msg, "%lu", tx); 148 cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false); 149 free(msg); 150 return 0; 151 } else if (!strcmp(argv[1], "getthrottle")) { 152 if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) { 153 cli->sendMsg(ResponseCode::CommandSyntaxError, 154 "Usage: interface getthrottle <interface> <rx|tx>", false); 155 return 0; 156 } 157 int val = 0; 158 int rc = 0; 159 int voldRc = ResponseCode::InterfaceRxThrottleResult; 160 161 if (!strcmp(argv[3], "rx")) { 162 rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val); 163 } else { 164 rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val); 165 voldRc = ResponseCode::InterfaceTxThrottleResult; 166 } 167 if (rc) { 168 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true); 169 } else { 170 char *msg = NULL; 171 asprintf(&msg, "%u", val); 172 cli->sendMsg(voldRc, msg, false); 173 free(msg); 174 return 0; 175 } 176 return 0; 177 } else if (!strcmp(argv[1], "setthrottle")) { 178 if (argc != 5) { 179 cli->sendMsg(ResponseCode::CommandSyntaxError, 180 "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false); 181 return 0; 182 } 183 if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) { 184 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true); 185 } else { 186 cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false); 187 } 188 return 0; 189 } else { 190 /* 191 * These commands take a minimum of 3 arguments 192 */ 193 if (argc < 3) { 194 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 195 return 0; 196 } 197 198 if (!strcmp(argv[1], "route")) { 199 int prefix_length = 0; 200 if (argc < 7) { 201 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 202 return 0; 203 } 204 if (sscanf(argv[5], "%d", &prefix_length) != 1) { 205 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false); 206 return 0; 207 } 208 if (!strcmp(argv[2], "add")) { 209 if (ifc_add_route(argv[3], argv[4], prefix_length, argv[6])) { 210 cli->sendMsg(ResponseCode::OperationFailed, "Failed to add route", true); 211 } else { 212 cli->sendMsg(ResponseCode::CommandOkay, "Route added", false); 213 } 214 } else if (!strcmp(argv[2], "remove")) { 215 if (ifc_remove_route(argv[3], argv[4], prefix_length, argv[6])) { 216 cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove route", true); 217 } else { 218 cli->sendMsg(ResponseCode::CommandOkay, "Route removed", false); 219 } 220 } else { 221 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 222 } 223 return 0; 224 } 225 226 if (!strcmp(argv[1], "getcfg")) { 227 struct in_addr addr; 228 int prefixLength; 229 unsigned char hwaddr[6]; 230 unsigned flags = 0; 231 232 ifc_init(); 233 memset(hwaddr, 0, sizeof(hwaddr)); 234 235 if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) { 236 cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); 237 ifc_close(); 238 return 0; 239 } 240 241 if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) { 242 LOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno)); 243 } 244 245 char *addr_s = strdup(inet_ntoa(addr)); 246 const char *updown, *brdcst, *loopbk, *ppp, *running, *multi; 247 248 updown = (flags & IFF_UP) ? "up" : "down"; 249 brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; 250 loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; 251 ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; 252 running = (flags & IFF_RUNNING) ? " running" : ""; 253 multi = (flags & IFF_MULTICAST) ? " multicast" : ""; 254 255 char *flag_s; 256 257 asprintf(&flag_s, "[%s%s%s%s%s%s]", updown, brdcst, loopbk, ppp, running, multi); 258 259 char *msg = NULL; 260 asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s", 261 hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5], 262 addr_s, prefixLength, flag_s); 263 264 cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false); 265 266 free(addr_s); 267 free(flag_s); 268 free(msg); 269 270 ifc_close(); 271 return 0; 272 } else if (!strcmp(argv[1], "setcfg")) { 273 // arglist: iface addr prefixLength [flags] 274 if (argc < 5) { 275 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 276 return 0; 277 } 278 LOGD("Setting iface cfg"); 279 280 struct in_addr addr; 281 unsigned flags = 0; 282 283 if (!inet_aton(argv[3], &addr)) { 284 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 285 return 0; 286 } 287 288 ifc_init(); 289 if (ifc_set_addr(argv[2], addr.s_addr)) { 290 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true); 291 ifc_close(); 292 return 0; 293 } 294 295 //Set prefix length on a non zero address 296 if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) { 297 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true); 298 ifc_close(); 299 return 0; 300 } 301 302 /* Process flags */ 303 /* read from "[XX" arg to "YY]" arg */ 304 bool bStarted = false; 305 for (int i = 5; i < argc; i++) { 306 char *flag = argv[i]; 307 if (!bStarted) { 308 if (*flag == '[') { 309 flag++; 310 bStarted = true; 311 } else { 312 continue; 313 } 314 } 315 int len = strlen(flag); 316 if (flag[len-1] == ']') { 317 i = argc; // stop after this loop 318 flag[len-1] = 0; 319 } 320 if (!strcmp(flag, "up")) { 321 LOGD("Trying to bring up %s", argv[2]); 322 if (ifc_up(argv[2])) { 323 LOGE("Error upping interface"); 324 cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true); 325 ifc_close(); 326 return 0; 327 } 328 } else if (!strcmp(flag, "down")) { 329 LOGD("Trying to bring down %s", argv[2]); 330 if (ifc_down(argv[2])) { 331 LOGE("Error downing interface"); 332 cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true); 333 ifc_close(); 334 return 0; 335 } 336 } else if (!strcmp(flag, "broadcast")) { 337 LOGD("broadcast flag ignored"); 338 } else if (!strcmp(flag, "multicast")) { 339 LOGD("multicast flag ignored"); 340 } else { 341 cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false); 342 ifc_close(); 343 return 0; 344 } 345 } 346 347 cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false); 348 ifc_close(); 349 return 0; 350 } else if (!strcmp(argv[1], "clearaddrs")) { 351 // arglist: iface 352 unsigned count, addr; 353 354 //IPv4 only right now 355 LOGD("Clearing all IP addresses on %s", argv[2]); 356 357 ifc_init(); 358 for (count=0, addr=1;((addr != 0) && (count < 255)); count++) { 359 if (ifc_get_addr(argv[2], &addr) < 0) 360 break; 361 if (addr) 362 ifc_set_addr(argv[2], 0); 363 } 364 ifc_close(); 365 cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false); 366 return 0; 367 } else { 368 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 369 return 0; 370 } 371 } 372 return 0; 373} 374 375 376CommandListener::ListTtysCmd::ListTtysCmd() : 377 NetdCommand("list_ttys") { 378} 379 380int CommandListener::ListTtysCmd::runCommand(SocketClient *cli, 381 int argc, char **argv) { 382 TtyCollection *tlist = sPppCtrl->getTtyList(); 383 TtyCollection::iterator it; 384 385 for (it = tlist->begin(); it != tlist->end(); ++it) { 386 cli->sendMsg(ResponseCode::TtyListResult, *it, false); 387 } 388 389 cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false); 390 return 0; 391} 392 393CommandListener::IpFwdCmd::IpFwdCmd() : 394 NetdCommand("ipfwd") { 395} 396 397int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 398 int argc, char **argv) { 399 int rc = 0; 400 401 if (argc < 2) { 402 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 403 return 0; 404 } 405 406 if (!strcmp(argv[1], "status")) { 407 char *tmp = NULL; 408 409 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 410 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 411 free(tmp); 412 return 0; 413 } else if (!strcmp(argv[1], "enable")) { 414 rc = sTetherCtrl->setIpFwdEnabled(true); 415 } else if (!strcmp(argv[1], "disable")) { 416 rc = sTetherCtrl->setIpFwdEnabled(false); 417 } else { 418 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 419 return 0; 420 } 421 422 if (!rc) { 423 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 424 } else { 425 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 426 } 427 428 return 0; 429} 430 431CommandListener::TetherCmd::TetherCmd() : 432 NetdCommand("tether") { 433} 434 435int CommandListener::TetherCmd::runCommand(SocketClient *cli, 436 int argc, char **argv) { 437 int rc = 0; 438 439 if (argc < 2) { 440 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 441 return 0; 442 } 443 444 if (!strcmp(argv[1], "stop")) { 445 rc = sTetherCtrl->stopTethering(); 446 } else if (!strcmp(argv[1], "status")) { 447 char *tmp = NULL; 448 449 asprintf(&tmp, "Tethering services %s", 450 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 451 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 452 free(tmp); 453 return 0; 454 } else { 455 /* 456 * These commands take a minimum of 4 arguments 457 */ 458 if (argc < 4) { 459 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 460 return 0; 461 } 462 463 if (!strcmp(argv[1], "start")) { 464 if (argc % 2 == 1) { 465 cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false); 466 return 0; 467 } 468 469 int num_addrs = argc - 2; 470 int arg_index = 2; 471 int array_index = 0; 472 in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs); 473 while (array_index < num_addrs) { 474 if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) { 475 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 476 free(addrs); 477 return 0; 478 } 479 } 480 rc = sTetherCtrl->startTethering(num_addrs, addrs); 481 free(addrs); 482 } else if (!strcmp(argv[1], "interface")) { 483 if (!strcmp(argv[2], "add")) { 484 rc = sTetherCtrl->tetherInterface(argv[3]); 485 } else if (!strcmp(argv[2], "remove")) { 486 rc = sTetherCtrl->untetherInterface(argv[3]); 487 } else if (!strcmp(argv[2], "list")) { 488 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 489 InterfaceCollection::iterator it; 490 491 for (it = ilist->begin(); it != ilist->end(); ++it) { 492 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 493 } 494 } else { 495 cli->sendMsg(ResponseCode::CommandParameterError, 496 "Unknown tether interface operation", false); 497 return 0; 498 } 499 } else if (!strcmp(argv[1], "dns")) { 500 if (!strcmp(argv[2], "set")) { 501 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 502 } else if (!strcmp(argv[2], "list")) { 503 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 504 NetAddressCollection::iterator it; 505 506 for (it = dlist->begin(); it != dlist->end(); ++it) { 507 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 508 } 509 } else { 510 cli->sendMsg(ResponseCode::CommandParameterError, 511 "Unknown tether interface operation", false); 512 return 0; 513 } 514 } else { 515 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 516 return 0; 517 } 518 } 519 520 if (!rc) { 521 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 522 } else { 523 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 524 } 525 526 return 0; 527} 528 529CommandListener::NatCmd::NatCmd() : 530 NetdCommand("nat") { 531} 532 533int CommandListener::NatCmd::runCommand(SocketClient *cli, 534 int argc, char **argv) { 535 int rc = 0; 536 537 if (argc < 3) { 538 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 539 return 0; 540 } 541 542 if (!strcmp(argv[1], "enable")) { 543 rc = sNatCtrl->enableNat(argv[2], argv[3]); 544 } else if (!strcmp(argv[1], "disable")) { 545 rc = sNatCtrl->disableNat(argv[2], argv[3]); 546 } else { 547 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 548 return 0; 549 } 550 551 if (!rc) { 552 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 553 } else { 554 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 555 } 556 557 return 0; 558} 559 560CommandListener::PppdCmd::PppdCmd() : 561 NetdCommand("pppd") { 562} 563 564int CommandListener::PppdCmd::runCommand(SocketClient *cli, 565 int argc, char **argv) { 566 int rc = 0; 567 568 if (argc < 3) { 569 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 570 return 0; 571 } 572 573 if (!strcmp(argv[1], "attach")) { 574 struct in_addr l, r, dns1, dns2; 575 576 memset(&dns1, sizeof(struct in_addr), 0); 577 memset(&dns2, sizeof(struct in_addr), 0); 578 579 if (!inet_aton(argv[3], &l)) { 580 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false); 581 return 0; 582 } 583 if (!inet_aton(argv[4], &r)) { 584 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false); 585 return 0; 586 } 587 if ((argc > 3) && (!inet_aton(argv[5], &dns1))) { 588 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false); 589 return 0; 590 } 591 if ((argc > 4) && (!inet_aton(argv[6], &dns2))) { 592 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false); 593 return 0; 594 } 595 rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2); 596 } else if (!strcmp(argv[1], "detach")) { 597 rc = sPppCtrl->detachPppd(argv[2]); 598 } else { 599 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false); 600 return 0; 601 } 602 603 if (!rc) { 604 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false); 605 } else { 606 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true); 607 } 608 609 return 0; 610} 611 612CommandListener::PanCmd::PanCmd() : 613 NetdCommand("pan") { 614} 615 616int CommandListener::PanCmd::runCommand(SocketClient *cli, 617 int argc, char **argv) { 618 int rc = 0; 619 620 if (argc < 2) { 621 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 622 return 0; 623 } 624 625 if (!strcmp(argv[1], "start")) { 626 rc = sPanCtrl->startPan(); 627 } else if (!strcmp(argv[1], "stop")) { 628 rc = sPanCtrl->stopPan(); 629 } else if (!strcmp(argv[1], "status")) { 630 char *tmp = NULL; 631 632 asprintf(&tmp, "Pan services %s", 633 (sPanCtrl->isPanStarted() ? "started" : "stopped")); 634 cli->sendMsg(ResponseCode::PanStatusResult, tmp, false); 635 free(tmp); 636 return 0; 637 } else { 638 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pan cmd", false); 639 return 0; 640 } 641 642 if (!rc) { 643 cli->sendMsg(ResponseCode::CommandOkay, "Pan operation succeeded", false); 644 } else { 645 cli->sendMsg(ResponseCode::OperationFailed, "Pan operation failed", true); 646 } 647 648 return 0; 649} 650 651CommandListener::SoftapCmd::SoftapCmd() : 652 NetdCommand("softap") { 653} 654 655int CommandListener::SoftapCmd::runCommand(SocketClient *cli, 656 int argc, char **argv) { 657 int rc = 0, flag = 0; 658 char *retbuf = NULL; 659 660 if (argc < 2) { 661 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false); 662 return 0; 663 } 664 665 if (!strcmp(argv[1], "start")) { 666 rc = sSoftapCtrl->startDriver(argv[2]); 667 } else if (!strcmp(argv[1], "stop")) { 668 rc = sSoftapCtrl->stopDriver(argv[2]); 669 } else if (!strcmp(argv[1], "startap")) { 670 rc = sSoftapCtrl->startSoftap(); 671 } else if (!strcmp(argv[1], "stopap")) { 672 rc = sSoftapCtrl->stopSoftap(); 673 } else if (!strcmp(argv[1], "fwreload")) { 674 rc = sSoftapCtrl->fwReloadSoftap(argc, argv); 675 } else if (!strcmp(argv[1], "clients")) { 676 rc = sSoftapCtrl->clientsSoftap(&retbuf); 677 if (!rc) { 678 cli->sendMsg(ResponseCode::CommandOkay, retbuf, false); 679 free(retbuf); 680 return 0; 681 } 682 } else if (!strcmp(argv[1], "status")) { 683 asprintf(&retbuf, "Softap service %s", 684 (sSoftapCtrl->isSoftapStarted() ? "started" : "stopped")); 685 cli->sendMsg(ResponseCode::SoftapStatusResult, retbuf, false); 686 free(retbuf); 687 return 0; 688 } else if (!strcmp(argv[1], "set")) { 689 rc = sSoftapCtrl->setSoftap(argc, argv); 690 } else { 691 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Unknown cmd", false); 692 return 0; 693 } 694 695 if (!rc) { 696 cli->sendMsg(ResponseCode::CommandOkay, "Softap operation succeeded", false); 697 } else { 698 cli->sendMsg(ResponseCode::OperationFailed, "Softap operation failed", true); 699 } 700 701 return 0; 702} 703 704CommandListener::ResolverCmd::ResolverCmd() : 705 NetdCommand("resolver") { 706} 707 708int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) { 709 int rc = 0; 710 struct in_addr addr; 711 712 if (argc < 2) { 713 cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false); 714 return 0; 715 } 716 717 if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>" 718 if (argc == 3) { 719 rc = sResolverCtrl->setDefaultInterface(argv[2]); 720 } else { 721 cli->sendMsg(ResponseCode::CommandSyntaxError, 722 "Wrong number of arguments to resolver setdefaultif", false); 723 return 0; 724 } 725 } else if (!strcmp(argv[1], "setifdns")) { // "resolver setifdns <iface> <dns1> <dns2> ..." 726 if (argc >= 4) { 727 rc = sResolverCtrl->setInterfaceDnsServers(argv[2], &argv[3], argc - 3); 728 } else { 729 cli->sendMsg(ResponseCode::CommandSyntaxError, 730 "Wrong number of arguments to resolver setifdns", false); 731 return 0; 732 } 733 734 // set the address of the interface to which the name servers 735 // are bound. Required in order to bind to right interface when 736 // doing the dns query. 737 if (!rc) { 738 ifc_init(); 739 ifc_get_info(argv[2], &addr.s_addr, NULL, 0); 740 741 rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr); 742 } 743 } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif" 744 if (argc == 2) { 745 rc = sResolverCtrl->flushDefaultDnsCache(); 746 } else { 747 cli->sendMsg(ResponseCode::CommandSyntaxError, 748 "Wrong number of arguments to resolver flushdefaultif", false); 749 return 0; 750 } 751 } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>" 752 if (argc == 3) { 753 rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]); 754 } else { 755 cli->sendMsg(ResponseCode::CommandSyntaxError, 756 "Wrong number of arguments to resolver setdefaultif", false); 757 return 0; 758 } 759 } else { 760 cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false); 761 return 0; 762 } 763 764 if (!rc) { 765 cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false); 766 } else { 767 cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true); 768 } 769 770 return 0; 771} 772 773int CommandListener::readInterfaceCounters(const char *iface, unsigned long *rx, unsigned long *tx) { 774 FILE *fp = fopen("/proc/net/dev", "r"); 775 if (!fp) { 776 LOGE("Failed to open /proc/net/dev (%s)", strerror(errno)); 777 return -1; 778 } 779 780 char buffer[512]; 781 782 fgets(buffer, sizeof(buffer), fp); // Header 1 783 fgets(buffer, sizeof(buffer), fp); // Header 2 784 while(fgets(buffer, sizeof(buffer), fp)) { 785 buffer[strlen(buffer)-1] = '\0'; 786 787 char name[31]; 788 unsigned long d; 789 sscanf(buffer, "%30s %lu %lu %lu %lu %lu %lu %lu %lu %lu", 790 name, rx, &d, &d, &d, &d, &d, &d, &d, tx); 791 char *rxString = strchr(name, ':'); 792 *rxString = '\0'; 793 rxString++; 794 // when the rx count gets too big it changes from "name: 999" to "name:1000" 795 // and the sscanf munge the two together. Detect that and fix 796 // note that all the %lu will be off by one and the real tx value will be in d 797 if (*rxString != '\0') { 798 *tx = d; 799 sscanf(rxString, "%20lu", rx); 800 } 801 if (strcmp(name, iface)) { 802 continue; 803 } 804 fclose(fp); 805 return 0; 806 } 807 808 fclose(fp); 809 *rx = 0; 810 *tx = 0; 811 return 0; 812} 813 814CommandListener::BandwidthControlCmd::BandwidthControlCmd() : 815 NetdCommand("bandwidth") { 816} 817 818int CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 819 int rc = 0; 820 LOGD("bwctrlcmd: argc=%d argv[0]=%s", argc, argv[0]); 821 if (argc < 2) { 822 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 823 return 0; 824 } 825 826 if (!strcmp(argv[1], "enable")) { 827 rc = sBandwidthCtrl->enableBandwidthControl(); 828 } else if (!strcmp(argv[1], "disable")) { 829 rc = sBandwidthCtrl->disableBandwidthControl(); 830 831 } else if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) { 832 if (argc != 3) { 833 cli->sendMsg(ResponseCode::CommandSyntaxError, 834 "Usage: bandwidth removequota <interface>", false); 835 return 0; 836 } 837 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]); 838 839 } else if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) { 840 int64_t bytes; 841 if (argc != 2) { 842 cli->sendMsg(ResponseCode::CommandSyntaxError, 843 "Usage: bandwidth getquota", false); 844 return 0; 845 } 846 rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes); 847 if (rc) { 848 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get quota", true); 849 return 0; 850 } 851 char *msg; 852 asprintf(&msg, "%lld", bytes); 853 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 854 free(msg); 855 856 } else if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) { 857 int64_t bytes; 858 if (argc != 3) { 859 cli->sendMsg(ResponseCode::CommandSyntaxError, 860 "Usage: bandwidth getiquota <iface>", false); 861 return 0; 862 } 863 rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes); 864 if (rc) { 865 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get quota", true); 866 return 0; 867 } 868 char *msg; 869 asprintf(&msg, "%lld", bytes); 870 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 871 free(msg); 872 873 } else if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) { 874 if (argc != 4) { 875 cli->sendMsg(ResponseCode::CommandSyntaxError, 876 "Usage: bandwidth setquota <interface> <bytes>", false); 877 return 0; 878 } 879 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3])); 880 881 } else if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) { 882 if (argc < 4) { 883 cli->sendMsg(ResponseCode::CommandSyntaxError, 884 "Usage: bandwidth setquotas <bytes> <interface> ...", false); 885 return 0; 886 } 887 for (int q = 3; argc >= 4; q++, argc--) { 888 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2])); 889 if (rc) { 890 char *msg; 891 asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]); 892 cli->sendMsg(ResponseCode::OperationFailed, 893 msg, false); 894 free(msg); 895 break; 896 } 897 } 898 899 } else if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) { 900 if (argc < 3) { 901 cli->sendMsg(ResponseCode::CommandSyntaxError, 902 "Usage: bandwidth removequotas <interface> ...", false); 903 return 0; 904 } 905 for (int q = 2; argc >= 3; q++, argc--) { 906 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]); 907 if (rc) { 908 char *msg; 909 asprintf(&msg, "bandwidth removequotas %s failed", argv[q]); 910 cli->sendMsg(ResponseCode::OperationFailed, 911 msg, false); 912 free(msg); 913 break; 914 } 915 } 916 917 } else if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) { 918 if (argc != 3) { 919 cli->sendMsg(ResponseCode::CommandSyntaxError, 920 "Usage: bandwidth removeiquota <interface>", false); 921 return 0; 922 } 923 rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]); 924 925 } else if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) { 926 if (argc != 4) { 927 cli->sendMsg(ResponseCode::CommandSyntaxError, 928 "Usage: bandwidth setiquota <interface> <bytes>", false); 929 return 0; 930 } 931 rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3])); 932 933 } else if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) { 934 if (argc < 3) { 935 cli->sendMsg(ResponseCode::CommandSyntaxError, 936 "Usage: bandwidth addnaughtyapps <appUid> ...", false); 937 return 0; 938 } 939 rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2); 940 941 } else if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) { 942 if (argc < 3) { 943 cli->sendMsg(ResponseCode::CommandSyntaxError, 944 "Usage: bandwidth removenaughtyapps <appUid> ...", false); 945 return 0; 946 } 947 rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2); 948 949 } else if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) { 950 if (argc != 3) { 951 cli->sendMsg(ResponseCode::CommandSyntaxError, 952 "Usage: bandwidth setglobalalert <bytes>", false); 953 return 0; 954 } 955 rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2])); 956 957 } else if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) { 958 if (argc != 2) { 959 cli->sendMsg(ResponseCode::CommandSyntaxError, 960 "Usage: bandwidth removeglobalalert", false); 961 return 0; 962 } 963 rc = sBandwidthCtrl->removeGlobalAlert(); 964 965 } else if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) { 966 if (argc != 3) { 967 cli->sendMsg(ResponseCode::CommandSyntaxError, 968 "Usage: bandwidth setsharedalert <bytes>", false); 969 return 0; 970 } 971 rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2])); 972 973 } else if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) { 974 if (argc != 2) { 975 cli->sendMsg(ResponseCode::CommandSyntaxError, 976 "Usage: bandwidth removesharedalert", false); 977 return 0; 978 } 979 rc = sBandwidthCtrl->removeSharedAlert(); 980 981 } else if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) { 982 if (argc != 4) { 983 cli->sendMsg(ResponseCode::CommandSyntaxError, 984 "Usage: bandwidth setinterfacealert <interface> <bytes>", false); 985 return 0; 986 } 987 rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3])); 988 989 } else if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) { 990 if (argc != 3) { 991 cli->sendMsg(ResponseCode::CommandSyntaxError, 992 "Usage: bandwidth removeinterfacealert <interface>", false); 993 return 0; 994 } 995 rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]); 996 997 } else { 998 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false); 999 return 0; 1000 } 1001 1002 if (!rc) { 1003 cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false); 1004 } else { 1005 cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", true); 1006 } 1007 return 0; 1008} 1009