CommandListener.cpp revision d8c64026aaae5a9987151b719bd840ec7d68747a
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#include "IdletimerController.h" 41#include "SecondaryTableController.h" 42#include "oem_iptables_hook.h" 43#include "NetdConstants.h" 44#include "FirewallController.h" 45 46TetherController *CommandListener::sTetherCtrl = NULL; 47NatController *CommandListener::sNatCtrl = NULL; 48PppController *CommandListener::sPppCtrl = NULL; 49PanController *CommandListener::sPanCtrl = NULL; 50SoftapController *CommandListener::sSoftapCtrl = NULL; 51BandwidthController * CommandListener::sBandwidthCtrl = NULL; 52IdletimerController * CommandListener::sIdletimerCtrl = NULL; 53ResolverController *CommandListener::sResolverCtrl = NULL; 54SecondaryTableController *CommandListener::sSecondaryTableCtrl = NULL; 55FirewallController *CommandListener::sFirewallCtrl = NULL; 56 57/** 58 * List of module chains to be created, along with explicit ordering. ORDERING 59 * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE. 60 */ 61static const char* FILTER_INPUT[] = { 62 // Bandwidth should always be early in input chain, to make sure we 63 // correctly count incoming traffic against data plan. 64 BandwidthController::LOCAL_INPUT, 65 FirewallController::LOCAL_INPUT, 66 NULL, 67}; 68 69static const char* FILTER_FORWARD[] = { 70 OEM_IPTABLES_FILTER_FORWARD, 71 FirewallController::LOCAL_FORWARD, 72 BandwidthController::LOCAL_FORWARD, 73 NatController::LOCAL_FORWARD, 74 NULL, 75}; 76 77static const char* FILTER_OUTPUT[] = { 78 OEM_IPTABLES_FILTER_OUTPUT, 79 FirewallController::LOCAL_OUTPUT, 80 BandwidthController::LOCAL_OUTPUT, 81 NULL, 82}; 83 84static const char* RAW_PREROUTING[] = { 85 BandwidthController::LOCAL_RAW_PREROUTING, 86 NULL, 87}; 88 89static const char* MANGLE_POSTROUTING[] = { 90 BandwidthController::LOCAL_MANGLE_POSTROUTING, 91 NULL, 92}; 93 94static const char* NAT_PREROUTING[] = { 95 OEM_IPTABLES_NAT_PREROUTING, 96 IdletimerController::LOCAL_NAT_PREROUTING, 97 NULL, 98}; 99 100static const char* NAT_POSTROUTING[] = { 101 IdletimerController::LOCAL_NAT_POSTROUTING, 102 NatController::LOCAL_NAT_POSTROUTING, 103 NULL, 104}; 105 106static void createChildChains(IptablesTarget target, const char* table, const char* parentChain, 107 const char** childChains) { 108 const char** childChain = childChains; 109 do { 110 // Order is important: 111 // -D to delete any pre-existing jump rule (removes references 112 // that would prevent -X from working) 113 // -F to flush any existing chain 114 // -X to delete any existing chain 115 // -N to create the chain 116 // -A to append the chain to parent 117 118 execIptablesSilently(target, "-t", table, "-D", parentChain, "-j", *childChain, NULL); 119 execIptablesSilently(target, "-t", table, "-F", *childChain, NULL); 120 execIptablesSilently(target, "-t", table, "-X", *childChain, NULL); 121 execIptables(target, "-t", table, "-N", *childChain, NULL); 122 execIptables(target, "-t", table, "-A", parentChain, "-j", *childChain, NULL); 123 } while (*(++childChain) != NULL); 124} 125 126CommandListener::CommandListener() : 127 FrameworkListener("netd", true) { 128 registerCmd(new InterfaceCmd()); 129 registerCmd(new IpFwdCmd()); 130 registerCmd(new TetherCmd()); 131 registerCmd(new NatCmd()); 132 registerCmd(new ListTtysCmd()); 133 registerCmd(new PppdCmd()); 134 registerCmd(new PanCmd()); 135 registerCmd(new SoftapCmd()); 136 registerCmd(new BandwidthControlCmd()); 137 registerCmd(new IdletimerControlCmd()); 138 registerCmd(new ResolverCmd()); 139 registerCmd(new FirewallCmd()); 140 141 if (!sSecondaryTableCtrl) 142 sSecondaryTableCtrl = new SecondaryTableController(); 143 if (!sTetherCtrl) 144 sTetherCtrl = new TetherController(); 145 if (!sNatCtrl) 146 sNatCtrl = new NatController(sSecondaryTableCtrl); 147 if (!sPppCtrl) 148 sPppCtrl = new PppController(); 149 if (!sPanCtrl) 150 sPanCtrl = new PanController(); 151 if (!sSoftapCtrl) 152 sSoftapCtrl = new SoftapController(); 153 if (!sBandwidthCtrl) 154 sBandwidthCtrl = new BandwidthController(); 155 if (!sIdletimerCtrl) 156 sIdletimerCtrl = new IdletimerController(); 157 if (!sResolverCtrl) 158 sResolverCtrl = new ResolverController(); 159 if (!sFirewallCtrl) 160 sFirewallCtrl = new FirewallController(); 161 162 /* 163 * This is the only time we touch top-level chains in iptables; controllers 164 * should only mutate rules inside of their children chains, as created by 165 * the constants above. 166 * 167 * Modules should never ACCEPT packets (except in well-justified cases); 168 * they should instead defer to any remaining modules using RETURN, or 169 * otherwise DROP/REJECT. 170 */ 171 172 // Create chains for children modules 173 createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT); 174 createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD); 175 createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT); 176 createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING); 177 createChildChains(V4V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING); 178 createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING); 179 createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING); 180 181 // Let each module setup their child chains 182 setupOemIptablesHook(); 183 184 /* When enabled, DROPs all packets except those matching rules. */ 185 sFirewallCtrl->setupIptablesHooks(); 186 187 /* Does DROPs in FORWARD by default */ 188 sNatCtrl->setupIptablesHooks(); 189 /* 190 * Does REJECT in INPUT, OUTPUT. Does counting also. 191 * No DROP/REJECT allowed later in netfilter-flow hook order. 192 */ 193 sBandwidthCtrl->setupIptablesHooks(); 194 /* 195 * Counts in nat: PREROUTING, POSTROUTING. 196 * No DROP/REJECT allowed later in netfilter-flow hook order. 197 */ 198 sIdletimerCtrl->setupIptablesHooks(); 199 200 sBandwidthCtrl->enableBandwidthControl(false); 201} 202 203CommandListener::InterfaceCmd::InterfaceCmd() : 204 NetdCommand("interface") { 205} 206 207int CommandListener::writeFile(const char *path, const char *value, int size) { 208 int fd = open(path, O_WRONLY); 209 if (fd < 0) { 210 ALOGE("Failed to open %s: %s", path, strerror(errno)); 211 return -1; 212 } 213 214 if (write(fd, value, size) != size) { 215 ALOGE("Failed to write %s: %s", path, strerror(errno)); 216 close(fd); 217 return -1; 218 } 219 close(fd); 220 return 0; 221} 222 223int CommandListener::InterfaceCmd::runCommand(SocketClient *cli, 224 int argc, char **argv) { 225 if (argc < 2) { 226 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 227 return 0; 228 } 229 230 if (!strcmp(argv[1], "list")) { 231 DIR *d; 232 struct dirent *de; 233 234 if (!(d = opendir("/sys/class/net"))) { 235 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true); 236 return 0; 237 } 238 239 while((de = readdir(d))) { 240 if (de->d_name[0] == '.') 241 continue; 242 cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false); 243 } 244 closedir(d); 245 cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false); 246 return 0; 247 } else if (!strcmp(argv[1], "readrxcounter")) { 248 if (argc != 3) { 249 cli->sendMsg(ResponseCode::CommandSyntaxError, 250 "Usage: interface readrxcounter <interface>", false); 251 return 0; 252 } 253 unsigned long rx = 0, tx = 0; 254 if (readInterfaceCounters(argv[2], &rx, &tx)) { 255 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 256 return 0; 257 } 258 259 char *msg; 260 asprintf(&msg, "%lu", rx); 261 cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false); 262 free(msg); 263 264 return 0; 265 } else if (!strcmp(argv[1], "readtxcounter")) { 266 if (argc != 3) { 267 cli->sendMsg(ResponseCode::CommandSyntaxError, 268 "Usage: interface readtxcounter <interface>", false); 269 return 0; 270 } 271 unsigned long rx = 0, tx = 0; 272 if (readInterfaceCounters(argv[2], &rx, &tx)) { 273 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 274 return 0; 275 } 276 277 char *msg = NULL; 278 asprintf(&msg, "%lu", tx); 279 cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false); 280 free(msg); 281 return 0; 282 } else if (!strcmp(argv[1], "getthrottle")) { 283 if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) { 284 cli->sendMsg(ResponseCode::CommandSyntaxError, 285 "Usage: interface getthrottle <interface> <rx|tx>", false); 286 return 0; 287 } 288 int val = 0; 289 int rc = 0; 290 int voldRc = ResponseCode::InterfaceRxThrottleResult; 291 292 if (!strcmp(argv[3], "rx")) { 293 rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val); 294 } else { 295 rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val); 296 voldRc = ResponseCode::InterfaceTxThrottleResult; 297 } 298 if (rc) { 299 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true); 300 } else { 301 char *msg = NULL; 302 asprintf(&msg, "%u", val); 303 cli->sendMsg(voldRc, msg, false); 304 free(msg); 305 return 0; 306 } 307 return 0; 308 } else if (!strcmp(argv[1], "setthrottle")) { 309 if (argc != 5) { 310 cli->sendMsg(ResponseCode::CommandSyntaxError, 311 "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false); 312 return 0; 313 } 314 if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) { 315 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true); 316 } else { 317 cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false); 318 } 319 return 0; 320 } else { 321 /* 322 * These commands take a minimum of 3 arguments 323 */ 324 if (argc < 3) { 325 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 326 return 0; 327 } 328 329 // 0 1 2 3 4 5 6 7 330 // interface route add/remove iface default/secondary dest prefix gateway 331 if (!strcmp(argv[1], "route")) { 332 int prefix_length = 0; 333 if (argc < 8) { 334 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 335 return 0; 336 } 337 if (sscanf(argv[6], "%d", &prefix_length) != 1) { 338 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false); 339 return 0; 340 } 341 if (!strcmp(argv[2], "add")) { 342 if (!strcmp(argv[4], "default")) { 343 if (ifc_add_route(argv[3], argv[5], prefix_length, argv[7])) { 344 cli->sendMsg(ResponseCode::OperationFailed, 345 "Failed to add route to default table", true); 346 } else { 347 cli->sendMsg(ResponseCode::CommandOkay, 348 "Route added to default table", false); 349 } 350 } else if (!strcmp(argv[4], "secondary")) { 351 return sSecondaryTableCtrl->addRoute(cli, argv[3], argv[5], 352 prefix_length, argv[7]); 353 } else { 354 cli->sendMsg(ResponseCode::CommandParameterError, 355 "Invalid route type, expecting 'default' or 'secondary'", false); 356 return 0; 357 } 358 } else if (!strcmp(argv[2], "remove")) { 359 if (!strcmp(argv[4], "default")) { 360 if (ifc_remove_route(argv[3], argv[5], prefix_length, argv[7])) { 361 cli->sendMsg(ResponseCode::OperationFailed, 362 "Failed to remove route from default table", true); 363 } else { 364 cli->sendMsg(ResponseCode::CommandOkay, 365 "Route removed from default table", false); 366 } 367 } else if (!strcmp(argv[4], "secondary")) { 368 return sSecondaryTableCtrl->removeRoute(cli, argv[3], argv[5], 369 prefix_length, argv[7]); 370 } else { 371 cli->sendMsg(ResponseCode::CommandParameterError, 372 "Invalid route type, expecting 'default' or 'secondary'", false); 373 return 0; 374 } 375 } else { 376 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 377 } 378 return 0; 379 } 380 381 if (!strcmp(argv[1], "getcfg")) { 382 struct in_addr addr; 383 int prefixLength; 384 unsigned char hwaddr[6]; 385 unsigned flags = 0; 386 387 ifc_init(); 388 memset(hwaddr, 0, sizeof(hwaddr)); 389 390 if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) { 391 cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); 392 ifc_close(); 393 return 0; 394 } 395 396 if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) { 397 ALOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno)); 398 } 399 400 char *addr_s = strdup(inet_ntoa(addr)); 401 const char *updown, *brdcst, *loopbk, *ppp, *running, *multi; 402 403 updown = (flags & IFF_UP) ? "up" : "down"; 404 brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; 405 loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; 406 ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; 407 running = (flags & IFF_RUNNING) ? " running" : ""; 408 multi = (flags & IFF_MULTICAST) ? " multicast" : ""; 409 410 char *flag_s; 411 412 asprintf(&flag_s, "%s%s%s%s%s%s", updown, brdcst, loopbk, ppp, running, multi); 413 414 char *msg = NULL; 415 asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s", 416 hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5], 417 addr_s, prefixLength, flag_s); 418 419 cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false); 420 421 free(addr_s); 422 free(flag_s); 423 free(msg); 424 425 ifc_close(); 426 return 0; 427 } else if (!strcmp(argv[1], "setcfg")) { 428 // arglist: iface [addr prefixLength] flags 429 if (argc < 4) { 430 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 431 return 0; 432 } 433 ALOGD("Setting iface cfg"); 434 435 struct in_addr addr; 436 unsigned flags = 0; 437 int index = 5; 438 439 ifc_init(); 440 441 if (!inet_aton(argv[3], &addr)) { 442 // Handle flags only case 443 index = 3; 444 } else { 445 if (ifc_set_addr(argv[2], addr.s_addr)) { 446 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true); 447 ifc_close(); 448 return 0; 449 } 450 451 // Set prefix length on a non zero address 452 if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) { 453 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true); 454 ifc_close(); 455 return 0; 456 } 457 } 458 459 /* Process flags */ 460 for (int i = index; i < argc; i++) { 461 char *flag = argv[i]; 462 if (!strcmp(flag, "up")) { 463 ALOGD("Trying to bring up %s", argv[2]); 464 if (ifc_up(argv[2])) { 465 ALOGE("Error upping interface"); 466 cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true); 467 ifc_close(); 468 return 0; 469 } 470 } else if (!strcmp(flag, "down")) { 471 ALOGD("Trying to bring down %s", argv[2]); 472 if (ifc_down(argv[2])) { 473 ALOGE("Error downing interface"); 474 cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true); 475 ifc_close(); 476 return 0; 477 } 478 } else if (!strcmp(flag, "broadcast")) { 479 // currently ignored 480 } else if (!strcmp(flag, "multicast")) { 481 // currently ignored 482 } else if (!strcmp(flag, "running")) { 483 // currently ignored 484 } else if (!strcmp(flag, "loopback")) { 485 // currently ignored 486 } else if (!strcmp(flag, "point-to-point")) { 487 // currently ignored 488 } else { 489 cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false); 490 ifc_close(); 491 return 0; 492 } 493 } 494 495 cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false); 496 ifc_close(); 497 return 0; 498 } else if (!strcmp(argv[1], "clearaddrs")) { 499 // arglist: iface 500 ALOGD("Clearing all IP addresses on %s", argv[2]); 501 502 ifc_clear_addresses(argv[2]); 503 504 cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false); 505 return 0; 506 } else if (!strcmp(argv[1], "ipv6privacyextensions")) { 507 if (argc != 4) { 508 cli->sendMsg(ResponseCode::CommandSyntaxError, 509 "Usage: interface ipv6privacyextensions <interface> <enable|disable>", 510 false); 511 return 0; 512 } 513 514 char *tmp; 515 asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/use_tempaddr", argv[2]); 516 517 if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "2" : "0", 1) < 0) { 518 free(tmp); 519 cli->sendMsg(ResponseCode::OperationFailed, 520 "Failed to set ipv6 privacy extensions", true); 521 return 0; 522 } 523 524 free(tmp); 525 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false); 526 return 0; 527 } else if (!strcmp(argv[1], "ipv6")) { 528 if (argc != 4) { 529 cli->sendMsg(ResponseCode::CommandSyntaxError, 530 "Usage: interface ipv6 <interface> <enable|disable>", 531 false); 532 return 0; 533 } 534 535 char *tmp; 536 asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", argv[2]); 537 538 if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "0" : "1", 1) < 0) { 539 free(tmp); 540 cli->sendMsg(ResponseCode::OperationFailed, 541 "Failed to change IPv6 state", true); 542 return 0; 543 } 544 545 free(tmp); 546 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false); 547 return 0; 548 } else { 549 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 550 return 0; 551 } 552 } 553 return 0; 554} 555 556 557CommandListener::ListTtysCmd::ListTtysCmd() : 558 NetdCommand("list_ttys") { 559} 560 561int CommandListener::ListTtysCmd::runCommand(SocketClient *cli, 562 int argc, char **argv) { 563 TtyCollection *tlist = sPppCtrl->getTtyList(); 564 TtyCollection::iterator it; 565 566 for (it = tlist->begin(); it != tlist->end(); ++it) { 567 cli->sendMsg(ResponseCode::TtyListResult, *it, false); 568 } 569 570 cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false); 571 return 0; 572} 573 574CommandListener::IpFwdCmd::IpFwdCmd() : 575 NetdCommand("ipfwd") { 576} 577 578int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 579 int argc, char **argv) { 580 int rc = 0; 581 582 if (argc < 2) { 583 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 584 return 0; 585 } 586 587 if (!strcmp(argv[1], "status")) { 588 char *tmp = NULL; 589 590 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 591 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 592 free(tmp); 593 return 0; 594 } else if (!strcmp(argv[1], "enable")) { 595 rc = sTetherCtrl->setIpFwdEnabled(true); 596 } else if (!strcmp(argv[1], "disable")) { 597 rc = sTetherCtrl->setIpFwdEnabled(false); 598 } else { 599 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 600 return 0; 601 } 602 603 if (!rc) { 604 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 605 } else { 606 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 607 } 608 609 return 0; 610} 611 612CommandListener::TetherCmd::TetherCmd() : 613 NetdCommand("tether") { 614} 615 616int CommandListener::TetherCmd::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], "stop")) { 626 rc = sTetherCtrl->stopTethering(); 627 } else if (!strcmp(argv[1], "status")) { 628 char *tmp = NULL; 629 630 asprintf(&tmp, "Tethering services %s", 631 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 632 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 633 free(tmp); 634 return 0; 635 } else { 636 /* 637 * These commands take a minimum of 4 arguments 638 */ 639 if (argc < 4) { 640 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 641 return 0; 642 } 643 644 if (!strcmp(argv[1], "start")) { 645 if (argc % 2 == 1) { 646 cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false); 647 return 0; 648 } 649 650 int num_addrs = argc - 2; 651 int arg_index = 2; 652 int array_index = 0; 653 in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs); 654 while (array_index < num_addrs) { 655 if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) { 656 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 657 free(addrs); 658 return 0; 659 } 660 } 661 rc = sTetherCtrl->startTethering(num_addrs, addrs); 662 free(addrs); 663 } else if (!strcmp(argv[1], "interface")) { 664 if (!strcmp(argv[2], "add")) { 665 rc = sTetherCtrl->tetherInterface(argv[3]); 666 } else if (!strcmp(argv[2], "remove")) { 667 rc = sTetherCtrl->untetherInterface(argv[3]); 668 } else if (!strcmp(argv[2], "list")) { 669 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 670 InterfaceCollection::iterator it; 671 672 for (it = ilist->begin(); it != ilist->end(); ++it) { 673 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 674 } 675 } else { 676 cli->sendMsg(ResponseCode::CommandParameterError, 677 "Unknown tether interface operation", false); 678 return 0; 679 } 680 } else if (!strcmp(argv[1], "dns")) { 681 if (!strcmp(argv[2], "set")) { 682 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 683 } else if (!strcmp(argv[2], "list")) { 684 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 685 NetAddressCollection::iterator it; 686 687 for (it = dlist->begin(); it != dlist->end(); ++it) { 688 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 689 } 690 } else { 691 cli->sendMsg(ResponseCode::CommandParameterError, 692 "Unknown tether interface operation", false); 693 return 0; 694 } 695 } else { 696 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 697 return 0; 698 } 699 } 700 701 if (!rc) { 702 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 703 } else { 704 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 705 } 706 707 return 0; 708} 709 710CommandListener::NatCmd::NatCmd() : 711 NetdCommand("nat") { 712} 713 714int CommandListener::NatCmd::runCommand(SocketClient *cli, 715 int argc, char **argv) { 716 int rc = 0; 717 718 if (argc < 5) { 719 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 720 return 0; 721 } 722 723 if (!strcmp(argv[1], "enable")) { 724 rc = sNatCtrl->enableNat(argc, argv); 725 if(!rc) { 726 /* Ignore ifaces for now. */ 727 rc = sBandwidthCtrl->setGlobalAlertInForwardChain(); 728 } 729 } else if (!strcmp(argv[1], "disable")) { 730 /* Ignore ifaces for now. */ 731 rc = sBandwidthCtrl->removeGlobalAlertInForwardChain(); 732 rc |= sNatCtrl->disableNat(argc, argv); 733 } else { 734 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 735 return 0; 736 } 737 738 if (!rc) { 739 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 740 } else { 741 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 742 } 743 744 return 0; 745} 746 747CommandListener::PppdCmd::PppdCmd() : 748 NetdCommand("pppd") { 749} 750 751int CommandListener::PppdCmd::runCommand(SocketClient *cli, 752 int argc, char **argv) { 753 int rc = 0; 754 755 if (argc < 3) { 756 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 757 return 0; 758 } 759 760 if (!strcmp(argv[1], "attach")) { 761 struct in_addr l, r, dns1, dns2; 762 763 memset(&dns1, sizeof(struct in_addr), 0); 764 memset(&dns2, sizeof(struct in_addr), 0); 765 766 if (!inet_aton(argv[3], &l)) { 767 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false); 768 return 0; 769 } 770 if (!inet_aton(argv[4], &r)) { 771 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false); 772 return 0; 773 } 774 if ((argc > 3) && (!inet_aton(argv[5], &dns1))) { 775 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false); 776 return 0; 777 } 778 if ((argc > 4) && (!inet_aton(argv[6], &dns2))) { 779 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false); 780 return 0; 781 } 782 rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2); 783 } else if (!strcmp(argv[1], "detach")) { 784 rc = sPppCtrl->detachPppd(argv[2]); 785 } else { 786 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false); 787 return 0; 788 } 789 790 if (!rc) { 791 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false); 792 } else { 793 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true); 794 } 795 796 return 0; 797} 798 799CommandListener::PanCmd::PanCmd() : 800 NetdCommand("pan") { 801} 802 803int CommandListener::PanCmd::runCommand(SocketClient *cli, 804 int argc, char **argv) { 805 int rc = 0; 806 807 if (argc < 2) { 808 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 809 return 0; 810 } 811 812 if (!strcmp(argv[1], "start")) { 813 rc = sPanCtrl->startPan(); 814 } else if (!strcmp(argv[1], "stop")) { 815 rc = sPanCtrl->stopPan(); 816 } else if (!strcmp(argv[1], "status")) { 817 char *tmp = NULL; 818 819 asprintf(&tmp, "Pan services %s", 820 (sPanCtrl->isPanStarted() ? "started" : "stopped")); 821 cli->sendMsg(ResponseCode::PanStatusResult, tmp, false); 822 free(tmp); 823 return 0; 824 } else { 825 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pan cmd", false); 826 return 0; 827 } 828 829 if (!rc) { 830 cli->sendMsg(ResponseCode::CommandOkay, "Pan operation succeeded", false); 831 } else { 832 cli->sendMsg(ResponseCode::OperationFailed, "Pan operation failed", true); 833 } 834 835 return 0; 836} 837 838CommandListener::SoftapCmd::SoftapCmd() : 839 NetdCommand("softap") { 840} 841 842int CommandListener::SoftapCmd::runCommand(SocketClient *cli, 843 int argc, char **argv) { 844 int rc = 0, flag = 0; 845 char *retbuf = NULL; 846 847 if (argc < 2) { 848 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false); 849 return 0; 850 } 851 852 if (!strcmp(argv[1], "startap")) { 853 rc = sSoftapCtrl->startSoftap(); 854 } else if (!strcmp(argv[1], "stopap")) { 855 rc = sSoftapCtrl->stopSoftap(); 856 } else if (!strcmp(argv[1], "fwreload")) { 857 rc = sSoftapCtrl->fwReloadSoftap(argc, argv); 858 } else if (!strcmp(argv[1], "clients")) { 859 rc = sSoftapCtrl->clientsSoftap(&retbuf); 860 if (!rc) { 861 cli->sendMsg(ResponseCode::CommandOkay, retbuf, false); 862 free(retbuf); 863 return 0; 864 } 865 } else if (!strcmp(argv[1], "status")) { 866 asprintf(&retbuf, "Softap service %s", 867 (sSoftapCtrl->isSoftapStarted() ? "started" : "stopped")); 868 cli->sendMsg(ResponseCode::SoftapStatusResult, retbuf, false); 869 free(retbuf); 870 return 0; 871 } else if (!strcmp(argv[1], "set")) { 872 rc = sSoftapCtrl->setSoftap(argc, argv); 873 } else { 874 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Unknown cmd", false); 875 return 0; 876 } 877 878 if (!rc) { 879 cli->sendMsg(ResponseCode::CommandOkay, "Softap operation succeeded", false); 880 } else { 881 cli->sendMsg(ResponseCode::OperationFailed, "Softap operation failed", true); 882 } 883 884 return 0; 885} 886 887CommandListener::ResolverCmd::ResolverCmd() : 888 NetdCommand("resolver") { 889} 890 891int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) { 892 int rc = 0; 893 struct in_addr addr; 894 895 if (argc < 2) { 896 cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false); 897 return 0; 898 } 899 900 if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>" 901 if (argc == 3) { 902 rc = sResolverCtrl->setDefaultInterface(argv[2]); 903 } else { 904 cli->sendMsg(ResponseCode::CommandSyntaxError, 905 "Wrong number of arguments to resolver setdefaultif", false); 906 return 0; 907 } 908 } else if (!strcmp(argv[1], "setifdns")) { // "resolver setifdns <iface> <dns1> <dns2> ..." 909 if (argc >= 4) { 910 rc = sResolverCtrl->setInterfaceDnsServers(argv[2], &argv[3], argc - 3); 911 } else { 912 cli->sendMsg(ResponseCode::CommandSyntaxError, 913 "Wrong number of arguments to resolver setifdns", false); 914 return 0; 915 } 916 917 // set the address of the interface to which the name servers 918 // are bound. Required in order to bind to right interface when 919 // doing the dns query. 920 if (!rc) { 921 ifc_init(); 922 ifc_get_info(argv[2], &addr.s_addr, NULL, 0); 923 924 rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr); 925 } 926 } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif" 927 if (argc == 2) { 928 rc = sResolverCtrl->flushDefaultDnsCache(); 929 } else { 930 cli->sendMsg(ResponseCode::CommandSyntaxError, 931 "Wrong number of arguments to resolver flushdefaultif", false); 932 return 0; 933 } 934 } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>" 935 if (argc == 3) { 936 rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]); 937 } else { 938 cli->sendMsg(ResponseCode::CommandSyntaxError, 939 "Wrong number of arguments to resolver setdefaultif", false); 940 return 0; 941 } 942 } else { 943 cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false); 944 return 0; 945 } 946 947 if (!rc) { 948 cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false); 949 } else { 950 cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true); 951 } 952 953 return 0; 954} 955 956int CommandListener::readInterfaceCounters(const char *iface, unsigned long *rx, unsigned long *tx) { 957 FILE *fp = fopen("/proc/net/dev", "r"); 958 if (!fp) { 959 ALOGE("Failed to open /proc/net/dev (%s)", strerror(errno)); 960 return -1; 961 } 962 963 char buffer[512]; 964 965 fgets(buffer, sizeof(buffer), fp); // Header 1 966 fgets(buffer, sizeof(buffer), fp); // Header 2 967 while(fgets(buffer, sizeof(buffer), fp)) { 968 buffer[strlen(buffer)-1] = '\0'; 969 970 char name[31]; 971 unsigned long d; 972 sscanf(buffer, "%30s %lu %lu %lu %lu %lu %lu %lu %lu %lu", 973 name, rx, &d, &d, &d, &d, &d, &d, &d, tx); 974 char *rxString = strchr(name, ':'); 975 *rxString = '\0'; 976 rxString++; 977 // when the rx count gets too big it changes from "name: 999" to "name:1000" 978 // and the sscanf munge the two together. Detect that and fix 979 // note that all the %lu will be off by one and the real tx value will be in d 980 if (*rxString != '\0') { 981 *tx = d; 982 sscanf(rxString, "%20lu", rx); 983 } 984 if (strcmp(name, iface)) { 985 continue; 986 } 987 fclose(fp); 988 return 0; 989 } 990 991 fclose(fp); 992 *rx = 0; 993 *tx = 0; 994 return 0; 995} 996 997CommandListener::BandwidthControlCmd::BandwidthControlCmd() : 998 NetdCommand("bandwidth") { 999} 1000 1001void CommandListener::BandwidthControlCmd::sendGenericSyntaxError(SocketClient *cli, const char *usageMsg) { 1002 char *msg; 1003 asprintf(&msg, "Usage: bandwidth %s", usageMsg); 1004 cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false); 1005 free(msg); 1006} 1007 1008void CommandListener::BandwidthControlCmd::sendGenericOkFail(SocketClient *cli, int cond) { 1009 if (!cond) { 1010 cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false); 1011 } else { 1012 cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false); 1013 } 1014} 1015 1016void CommandListener::BandwidthControlCmd::sendGenericOpFailed(SocketClient *cli, const char *errMsg) { 1017 cli->sendMsg(ResponseCode::OperationFailed, errMsg, false); 1018} 1019 1020int CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 1021 if (argc < 2) { 1022 sendGenericSyntaxError(cli, "<cmds> <args...>"); 1023 return 0; 1024 } 1025 1026 ALOGV("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]); 1027 1028 if (!strcmp(argv[1], "enable")) { 1029 int rc = sBandwidthCtrl->enableBandwidthControl(true); 1030 sendGenericOkFail(cli, rc); 1031 return 0; 1032 1033 } 1034 if (!strcmp(argv[1], "disable")) { 1035 int rc = sBandwidthCtrl->disableBandwidthControl(); 1036 sendGenericOkFail(cli, rc); 1037 return 0; 1038 1039 } 1040 if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) { 1041 if (argc != 3) { 1042 sendGenericSyntaxError(cli, "removequota <interface>"); 1043 return 0; 1044 } 1045 int rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]); 1046 sendGenericOkFail(cli, rc); 1047 return 0; 1048 1049 } 1050 if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) { 1051 int64_t bytes; 1052 if (argc != 2) { 1053 sendGenericSyntaxError(cli, "getquota"); 1054 return 0; 1055 } 1056 int rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes); 1057 if (rc) { 1058 sendGenericOpFailed(cli, "Failed to get quota"); 1059 return 0; 1060 } 1061 1062 char *msg; 1063 asprintf(&msg, "%lld", bytes); 1064 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 1065 free(msg); 1066 return 0; 1067 1068 } 1069 if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) { 1070 int64_t bytes; 1071 if (argc != 3) { 1072 sendGenericSyntaxError(cli, "getiquota <iface>"); 1073 return 0; 1074 } 1075 1076 int rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes); 1077 if (rc) { 1078 sendGenericOpFailed(cli, "Failed to get quota"); 1079 return 0; 1080 } 1081 char *msg; 1082 asprintf(&msg, "%lld", bytes); 1083 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 1084 free(msg); 1085 return 0; 1086 1087 } 1088 if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) { 1089 if (argc != 4) { 1090 sendGenericSyntaxError(cli, "setquota <interface> <bytes>"); 1091 return 0; 1092 } 1093 int rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3])); 1094 sendGenericOkFail(cli, rc); 1095 return 0; 1096 } 1097 if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) { 1098 int rc; 1099 if (argc < 4) { 1100 sendGenericSyntaxError(cli, "setquotas <bytes> <interface> ..."); 1101 return 0; 1102 } 1103 1104 for (int q = 3; argc >= 4; q++, argc--) { 1105 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2])); 1106 if (rc) { 1107 char *msg; 1108 asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]); 1109 cli->sendMsg(ResponseCode::OperationFailed, 1110 msg, false); 1111 free(msg); 1112 return 0; 1113 } 1114 } 1115 sendGenericOkFail(cli, rc); 1116 return 0; 1117 1118 } 1119 if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) { 1120 int rc; 1121 if (argc < 3) { 1122 sendGenericSyntaxError(cli, "removequotas <interface> ..."); 1123 return 0; 1124 } 1125 1126 for (int q = 2; argc >= 3; q++, argc--) { 1127 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]); 1128 if (rc) { 1129 char *msg; 1130 asprintf(&msg, "bandwidth removequotas %s failed", argv[q]); 1131 cli->sendMsg(ResponseCode::OperationFailed, 1132 msg, false); 1133 free(msg); 1134 return 0; 1135 } 1136 } 1137 sendGenericOkFail(cli, rc); 1138 return 0; 1139 1140 } 1141 if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) { 1142 if (argc != 3) { 1143 sendGenericSyntaxError(cli, "removeiquota <interface>"); 1144 return 0; 1145 } 1146 int rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]); 1147 sendGenericOkFail(cli, rc); 1148 return 0; 1149 1150 } 1151 if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) { 1152 if (argc != 4) { 1153 sendGenericSyntaxError(cli, "setiquota <interface> <bytes>"); 1154 return 0; 1155 } 1156 int rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3])); 1157 sendGenericOkFail(cli, rc); 1158 return 0; 1159 1160 } 1161 if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) { 1162 if (argc < 3) { 1163 sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ..."); 1164 return 0; 1165 } 1166 int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2); 1167 sendGenericOkFail(cli, rc); 1168 return 0; 1169 1170 1171 } 1172 if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) { 1173 if (argc < 3) { 1174 sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ..."); 1175 return 0; 1176 } 1177 int rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2); 1178 sendGenericOkFail(cli, rc); 1179 return 0; 1180 1181 } 1182 if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) { 1183 if (argc != 3) { 1184 sendGenericSyntaxError(cli, "setglobalalert <bytes>"); 1185 return 0; 1186 } 1187 int rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2])); 1188 sendGenericOkFail(cli, rc); 1189 return 0; 1190 1191 } 1192 if (!strcmp(argv[1], "debugsettetherglobalalert") || !strcmp(argv[1], "dstga")) { 1193 if (argc != 4) { 1194 sendGenericSyntaxError(cli, "debugsettetherglobalalert <interface0> <interface1>"); 1195 return 0; 1196 } 1197 /* We ignore the interfaces for now. */ 1198 int rc = sBandwidthCtrl->setGlobalAlertInForwardChain(); 1199 sendGenericOkFail(cli, rc); 1200 return 0; 1201 1202 } 1203 if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) { 1204 if (argc != 2) { 1205 sendGenericSyntaxError(cli, "removeglobalalert"); 1206 return 0; 1207 } 1208 int rc = sBandwidthCtrl->removeGlobalAlert(); 1209 sendGenericOkFail(cli, rc); 1210 return 0; 1211 1212 } 1213 if (!strcmp(argv[1], "debugremovetetherglobalalert") || !strcmp(argv[1], "drtga")) { 1214 if (argc != 4) { 1215 sendGenericSyntaxError(cli, "debugremovetetherglobalalert <interface0> <interface1>"); 1216 return 0; 1217 } 1218 /* We ignore the interfaces for now. */ 1219 int rc = sBandwidthCtrl->removeGlobalAlertInForwardChain(); 1220 sendGenericOkFail(cli, rc); 1221 return 0; 1222 1223 } 1224 if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) { 1225 if (argc != 3) { 1226 sendGenericSyntaxError(cli, "setsharedalert <bytes>"); 1227 return 0; 1228 } 1229 int rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2])); 1230 sendGenericOkFail(cli, rc); 1231 return 0; 1232 1233 } 1234 if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) { 1235 if (argc != 2) { 1236 sendGenericSyntaxError(cli, "removesharedalert"); 1237 return 0; 1238 } 1239 int rc = sBandwidthCtrl->removeSharedAlert(); 1240 sendGenericOkFail(cli, rc); 1241 return 0; 1242 1243 } 1244 if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) { 1245 if (argc != 4) { 1246 sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>"); 1247 return 0; 1248 } 1249 int rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3])); 1250 sendGenericOkFail(cli, rc); 1251 return 0; 1252 1253 } 1254 if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) { 1255 if (argc != 3) { 1256 sendGenericSyntaxError(cli, "removeinterfacealert <interface>"); 1257 return 0; 1258 } 1259 int rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]); 1260 sendGenericOkFail(cli, rc); 1261 return 0; 1262 1263 } 1264 if (!strcmp(argv[1], "gettetherstats") || !strcmp(argv[1], "gts")) { 1265 BandwidthController::TetherStats tetherStats; 1266 std::string extraProcessingInfo = ""; 1267 if (argc != 4) { 1268 sendGenericSyntaxError(cli, "gettetherstats <interface0> <interface1>"); 1269 return 0; 1270 } 1271 1272 tetherStats.ifaceIn = argv[2]; 1273 tetherStats.ifaceOut = argv[3]; 1274 int rc = sBandwidthCtrl->getTetherStats(tetherStats, extraProcessingInfo); 1275 if (rc) { 1276 extraProcessingInfo.insert(0, "Failed to get tethering stats.\n"); 1277 sendGenericOpFailed(cli, extraProcessingInfo.c_str()); 1278 return 0; 1279 } 1280 1281 char *msg = tetherStats.getStatsLine(); 1282 cli->sendMsg(ResponseCode::TetheringStatsResult, msg, false); 1283 free(msg); 1284 return 0; 1285 1286 } 1287 1288 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false); 1289 return 0; 1290} 1291 1292CommandListener::IdletimerControlCmd::IdletimerControlCmd() : 1293 NetdCommand("idletimer") { 1294} 1295 1296int CommandListener::IdletimerControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 1297 // TODO(ashish): Change the error statements 1298 if (argc < 2) { 1299 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1300 return 0; 1301 } 1302 1303 ALOGV("idletimerctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]); 1304 1305 if (!strcmp(argv[1], "enable")) { 1306 if (0 != sIdletimerCtrl->enableIdletimerControl()) { 1307 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1308 } else { 1309 cli->sendMsg(ResponseCode::CommandOkay, "Enable success", false); 1310 } 1311 return 0; 1312 1313 } 1314 if (!strcmp(argv[1], "disable")) { 1315 if (0 != sIdletimerCtrl->disableIdletimerControl()) { 1316 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1317 } else { 1318 cli->sendMsg(ResponseCode::CommandOkay, "Disable success", false); 1319 } 1320 return 0; 1321 } 1322 if (!strcmp(argv[1], "add")) { 1323 if (argc != 5) { 1324 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1325 return 0; 1326 } 1327 if(0 != sIdletimerCtrl->addInterfaceIdletimer( 1328 argv[2], atoi(argv[3]), argv[4])) { 1329 cli->sendMsg(ResponseCode::OperationFailed, "Failed to add interface", false); 1330 } else { 1331 cli->sendMsg(ResponseCode::CommandOkay, "Add success", false); 1332 } 1333 return 0; 1334 } 1335 if (!strcmp(argv[1], "remove")) { 1336 if (argc != 5) { 1337 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1338 return 0; 1339 } 1340 // ashish: fixme timeout 1341 if (0 != sIdletimerCtrl->removeInterfaceIdletimer( 1342 argv[2], atoi(argv[3]), argv[4])) { 1343 cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove interface", false); 1344 } else { 1345 cli->sendMsg(ResponseCode::CommandOkay, "Remove success", false); 1346 } 1347 return 0; 1348 } 1349 1350 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown idletimer cmd", false); 1351 return 0; 1352} 1353 1354CommandListener::FirewallCmd::FirewallCmd() : 1355 NetdCommand("firewall") { 1356} 1357 1358int CommandListener::FirewallCmd::sendGenericOkFail(SocketClient *cli, int cond) { 1359 if (!cond) { 1360 cli->sendMsg(ResponseCode::CommandOkay, "Firewall command succeeded", false); 1361 } else { 1362 cli->sendMsg(ResponseCode::OperationFailed, "Firewall command failed", false); 1363 } 1364 return 0; 1365} 1366 1367FirewallRule CommandListener::FirewallCmd::parseRule(const char* arg) { 1368 if (!strcmp(arg, "allow")) { 1369 return ALLOW; 1370 } else { 1371 return DENY; 1372 } 1373} 1374 1375int CommandListener::FirewallCmd::runCommand(SocketClient *cli, int argc, 1376 char **argv) { 1377 if (argc < 2) { 1378 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false); 1379 return 0; 1380 } 1381 1382 if (!strcmp(argv[1], "enable")) { 1383 int res = sFirewallCtrl->enableFirewall(); 1384 return sendGenericOkFail(cli, res); 1385 } 1386 if (!strcmp(argv[1], "disable")) { 1387 int res = sFirewallCtrl->disableFirewall(); 1388 return sendGenericOkFail(cli, res); 1389 } 1390 if (!strcmp(argv[1], "is_enabled")) { 1391 int res = sFirewallCtrl->isFirewallEnabled(); 1392 return sendGenericOkFail(cli, res); 1393 } 1394 1395 if (!strcmp(argv[1], "set_interface_rule")) { 1396 if (argc != 4) { 1397 cli->sendMsg(ResponseCode::CommandSyntaxError, 1398 "Usage: firewall set_interface_rule <rmnet0> <allow|deny>", false); 1399 return 0; 1400 } 1401 1402 const char* iface = argv[2]; 1403 FirewallRule rule = parseRule(argv[3]); 1404 1405 int res = sFirewallCtrl->setInterfaceRule(iface, rule); 1406 return sendGenericOkFail(cli, res); 1407 } 1408 1409 if (!strcmp(argv[1], "set_egress_source_rule")) { 1410 if (argc != 4) { 1411 cli->sendMsg(ResponseCode::CommandSyntaxError, 1412 "Usage: firewall set_egress_source_rule <192.168.0.1> <allow|deny>", 1413 false); 1414 return 0; 1415 } 1416 1417 const char* addr = argv[2]; 1418 FirewallRule rule = parseRule(argv[3]); 1419 1420 int res = sFirewallCtrl->setEgressSourceRule(addr, rule); 1421 return sendGenericOkFail(cli, res); 1422 } 1423 1424 if (!strcmp(argv[1], "set_egress_dest_rule")) { 1425 if (argc != 5) { 1426 cli->sendMsg(ResponseCode::CommandSyntaxError, 1427 "Usage: firewall set_egress_dest_rule <192.168.0.1> <80> <allow|deny>", 1428 false); 1429 return 0; 1430 } 1431 1432 const char* addr = argv[2]; 1433 int port = atoi(argv[3]); 1434 FirewallRule rule = parseRule(argv[4]); 1435 1436 int res = 0; 1437 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_TCP, port, rule); 1438 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_UDP, port, rule); 1439 return sendGenericOkFail(cli, res); 1440 } 1441 1442 if (!strcmp(argv[1], "set_uid_rule")) { 1443 if (argc != 4) { 1444 cli->sendMsg(ResponseCode::CommandSyntaxError, 1445 "Usage: firewall set_uid_rule <1000> <allow|deny>", 1446 false); 1447 return 0; 1448 } 1449 1450 int uid = atoi(argv[2]); 1451 FirewallRule rule = parseRule(argv[3]); 1452 1453 int res = sFirewallCtrl->setUidRule(uid, rule); 1454 return sendGenericOkFail(cli, res); 1455 } 1456 1457 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false); 1458 return 0; 1459} 1460