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