CommandListener.cpp revision 72779ad68ae5d2151d15a30791ca7203f3cb3026
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], "start-reverse")) { 628 ALOGD("CommandListener::TetherCmd::run, call startReverseTethering, iface:%s", argv[2]); 629 sTetherCtrl->startReverseTethering(argv[2]); 630 } else if (!strcmp(argv[1], "stop-reverse")) { 631 ALOGD("CommandListener::TetherCmd::run, call stopReverseTethering"); 632 rc = sTetherCtrl->stopReverseTethering(); 633 } else if (!strcmp(argv[1], "status")) { 634 char *tmp = NULL; 635 636 asprintf(&tmp, "Tethering services %s", 637 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 638 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 639 free(tmp); 640 return 0; 641 } else { 642 /* 643 * These commands take a minimum of 4 arguments 644 */ 645 if (argc < 4) { 646 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 647 return 0; 648 } 649 650 if (!strcmp(argv[1], "start")) { 651 if (argc % 2 == 1) { 652 cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false); 653 return 0; 654 } 655 656 int num_addrs = argc - 2; 657 int arg_index = 2; 658 int array_index = 0; 659 in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs); 660 while (array_index < num_addrs) { 661 if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) { 662 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 663 free(addrs); 664 return 0; 665 } 666 } 667 rc = sTetherCtrl->startTethering(num_addrs, addrs); 668 free(addrs); 669 } else if (!strcmp(argv[1], "interface")) { 670 if (!strcmp(argv[2], "add")) { 671 rc = sTetherCtrl->tetherInterface(argv[3]); 672 } else if (!strcmp(argv[2], "remove")) { 673 rc = sTetherCtrl->untetherInterface(argv[3]); 674 } else if (!strcmp(argv[2], "list")) { 675 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 676 InterfaceCollection::iterator it; 677 678 for (it = ilist->begin(); it != ilist->end(); ++it) { 679 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 680 } 681 } else { 682 cli->sendMsg(ResponseCode::CommandParameterError, 683 "Unknown tether interface operation", false); 684 return 0; 685 } 686 } else if (!strcmp(argv[1], "dns")) { 687 if (!strcmp(argv[2], "set")) { 688 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 689 } else if (!strcmp(argv[2], "list")) { 690 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 691 NetAddressCollection::iterator it; 692 693 for (it = dlist->begin(); it != dlist->end(); ++it) { 694 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 695 } 696 } else { 697 cli->sendMsg(ResponseCode::CommandParameterError, 698 "Unknown tether interface operation", false); 699 return 0; 700 } 701 } else { 702 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 703 return 0; 704 } 705 } 706 707 if (!rc) { 708 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 709 } else { 710 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 711 } 712 713 return 0; 714} 715 716CommandListener::NatCmd::NatCmd() : 717 NetdCommand("nat") { 718} 719 720int CommandListener::NatCmd::runCommand(SocketClient *cli, 721 int argc, char **argv) { 722 int rc = 0; 723 724 if (argc < 5) { 725 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 726 return 0; 727 } 728 729 if (!strcmp(argv[1], "enable")) { 730 rc = sNatCtrl->enableNat(argc, argv); 731 if(!rc) { 732 /* Ignore ifaces for now. */ 733 rc = sBandwidthCtrl->setGlobalAlertInForwardChain(); 734 } 735 } else if (!strcmp(argv[1], "disable")) { 736 /* Ignore ifaces for now. */ 737 rc = sBandwidthCtrl->removeGlobalAlertInForwardChain(); 738 rc |= sNatCtrl->disableNat(argc, argv); 739 } else { 740 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 741 return 0; 742 } 743 744 if (!rc) { 745 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 746 } else { 747 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 748 } 749 750 return 0; 751} 752 753CommandListener::PppdCmd::PppdCmd() : 754 NetdCommand("pppd") { 755} 756 757int CommandListener::PppdCmd::runCommand(SocketClient *cli, 758 int argc, char **argv) { 759 int rc = 0; 760 761 if (argc < 3) { 762 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 763 return 0; 764 } 765 766 if (!strcmp(argv[1], "attach")) { 767 struct in_addr l, r, dns1, dns2; 768 769 memset(&dns1, sizeof(struct in_addr), 0); 770 memset(&dns2, sizeof(struct in_addr), 0); 771 772 if (!inet_aton(argv[3], &l)) { 773 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false); 774 return 0; 775 } 776 if (!inet_aton(argv[4], &r)) { 777 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false); 778 return 0; 779 } 780 if ((argc > 3) && (!inet_aton(argv[5], &dns1))) { 781 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false); 782 return 0; 783 } 784 if ((argc > 4) && (!inet_aton(argv[6], &dns2))) { 785 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false); 786 return 0; 787 } 788 rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2); 789 } else if (!strcmp(argv[1], "detach")) { 790 rc = sPppCtrl->detachPppd(argv[2]); 791 } else { 792 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false); 793 return 0; 794 } 795 796 if (!rc) { 797 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false); 798 } else { 799 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true); 800 } 801 802 return 0; 803} 804 805CommandListener::PanCmd::PanCmd() : 806 NetdCommand("pan") { 807} 808 809int CommandListener::PanCmd::runCommand(SocketClient *cli, 810 int argc, char **argv) { 811 int rc = 0; 812 813 if (argc < 2) { 814 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 815 return 0; 816 } 817 818 if (!strcmp(argv[1], "start")) { 819 rc = sPanCtrl->startPan(); 820 } else if (!strcmp(argv[1], "stop")) { 821 rc = sPanCtrl->stopPan(); 822 } else if (!strcmp(argv[1], "status")) { 823 char *tmp = NULL; 824 825 asprintf(&tmp, "Pan services %s", 826 (sPanCtrl->isPanStarted() ? "started" : "stopped")); 827 cli->sendMsg(ResponseCode::PanStatusResult, tmp, false); 828 free(tmp); 829 return 0; 830 } else { 831 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pan cmd", false); 832 return 0; 833 } 834 835 if (!rc) { 836 cli->sendMsg(ResponseCode::CommandOkay, "Pan operation succeeded", false); 837 } else { 838 cli->sendMsg(ResponseCode::OperationFailed, "Pan operation failed", true); 839 } 840 841 return 0; 842} 843 844CommandListener::SoftapCmd::SoftapCmd() : 845 NetdCommand("softap") { 846} 847 848int CommandListener::SoftapCmd::runCommand(SocketClient *cli, 849 int argc, char **argv) { 850 int rc = 0, flag = 0; 851 char *retbuf = NULL; 852 853 if (argc < 2) { 854 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false); 855 return 0; 856 } 857 858 if (!strcmp(argv[1], "startap")) { 859 rc = sSoftapCtrl->startSoftap(); 860 } else if (!strcmp(argv[1], "stopap")) { 861 rc = sSoftapCtrl->stopSoftap(); 862 } else if (!strcmp(argv[1], "fwreload")) { 863 rc = sSoftapCtrl->fwReloadSoftap(argc, argv); 864 } else if (!strcmp(argv[1], "clients")) { 865 rc = sSoftapCtrl->clientsSoftap(&retbuf); 866 if (!rc) { 867 cli->sendMsg(ResponseCode::CommandOkay, retbuf, false); 868 free(retbuf); 869 return 0; 870 } 871 } else if (!strcmp(argv[1], "status")) { 872 asprintf(&retbuf, "Softap service %s", 873 (sSoftapCtrl->isSoftapStarted() ? "started" : "stopped")); 874 cli->sendMsg(ResponseCode::SoftapStatusResult, retbuf, false); 875 free(retbuf); 876 return 0; 877 } else if (!strcmp(argv[1], "set")) { 878 rc = sSoftapCtrl->setSoftap(argc, argv); 879 } else { 880 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Unknown cmd", false); 881 return 0; 882 } 883 884 if (!rc) { 885 cli->sendMsg(ResponseCode::CommandOkay, "Softap operation succeeded", false); 886 } else { 887 cli->sendMsg(ResponseCode::OperationFailed, "Softap operation failed", true); 888 } 889 890 return 0; 891} 892 893CommandListener::ResolverCmd::ResolverCmd() : 894 NetdCommand("resolver") { 895} 896 897int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) { 898 int rc = 0; 899 struct in_addr addr; 900 901 if (argc < 2) { 902 cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false); 903 return 0; 904 } 905 906 if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>" 907 if (argc == 3) { 908 rc = sResolverCtrl->setDefaultInterface(argv[2]); 909 } else { 910 cli->sendMsg(ResponseCode::CommandSyntaxError, 911 "Wrong number of arguments to resolver setdefaultif", false); 912 return 0; 913 } 914 } else if (!strcmp(argv[1], "setifdns")) { // "resolver setifdns <iface> <dns1> <dns2> ..." 915 if (argc >= 4) { 916 rc = sResolverCtrl->setInterfaceDnsServers(argv[2], &argv[3], argc - 3); 917 } else { 918 cli->sendMsg(ResponseCode::CommandSyntaxError, 919 "Wrong number of arguments to resolver setifdns", false); 920 return 0; 921 } 922 923 // set the address of the interface to which the name servers 924 // are bound. Required in order to bind to right interface when 925 // doing the dns query. 926 if (!rc) { 927 ifc_init(); 928 ifc_get_info(argv[2], &addr.s_addr, NULL, 0); 929 930 rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr); 931 } 932 } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif" 933 if (argc == 2) { 934 rc = sResolverCtrl->flushDefaultDnsCache(); 935 } else { 936 cli->sendMsg(ResponseCode::CommandSyntaxError, 937 "Wrong number of arguments to resolver flushdefaultif", false); 938 return 0; 939 } 940 } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>" 941 if (argc == 3) { 942 rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]); 943 } else { 944 cli->sendMsg(ResponseCode::CommandSyntaxError, 945 "Wrong number of arguments to resolver setdefaultif", false); 946 return 0; 947 } 948 } else { 949 cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false); 950 return 0; 951 } 952 953 if (!rc) { 954 cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false); 955 } else { 956 cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true); 957 } 958 959 return 0; 960} 961 962int CommandListener::readInterfaceCounters(const char *iface, unsigned long *rx, unsigned long *tx) { 963 FILE *fp = fopen("/proc/net/dev", "r"); 964 if (!fp) { 965 ALOGE("Failed to open /proc/net/dev (%s)", strerror(errno)); 966 return -1; 967 } 968 969 char buffer[512]; 970 971 fgets(buffer, sizeof(buffer), fp); // Header 1 972 fgets(buffer, sizeof(buffer), fp); // Header 2 973 while(fgets(buffer, sizeof(buffer), fp)) { 974 buffer[strlen(buffer)-1] = '\0'; 975 976 char name[31]; 977 unsigned long d; 978 sscanf(buffer, "%30s %lu %lu %lu %lu %lu %lu %lu %lu %lu", 979 name, rx, &d, &d, &d, &d, &d, &d, &d, tx); 980 char *rxString = strchr(name, ':'); 981 *rxString = '\0'; 982 rxString++; 983 // when the rx count gets too big it changes from "name: 999" to "name:1000" 984 // and the sscanf munge the two together. Detect that and fix 985 // note that all the %lu will be off by one and the real tx value will be in d 986 if (*rxString != '\0') { 987 *tx = d; 988 sscanf(rxString, "%20lu", rx); 989 } 990 if (strcmp(name, iface)) { 991 continue; 992 } 993 fclose(fp); 994 return 0; 995 } 996 997 fclose(fp); 998 *rx = 0; 999 *tx = 0; 1000 return 0; 1001} 1002 1003CommandListener::BandwidthControlCmd::BandwidthControlCmd() : 1004 NetdCommand("bandwidth") { 1005} 1006 1007void CommandListener::BandwidthControlCmd::sendGenericSyntaxError(SocketClient *cli, const char *usageMsg) { 1008 char *msg; 1009 asprintf(&msg, "Usage: bandwidth %s", usageMsg); 1010 cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false); 1011 free(msg); 1012} 1013 1014void CommandListener::BandwidthControlCmd::sendGenericOkFail(SocketClient *cli, int cond) { 1015 if (!cond) { 1016 cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false); 1017 } else { 1018 cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false); 1019 } 1020} 1021 1022void CommandListener::BandwidthControlCmd::sendGenericOpFailed(SocketClient *cli, const char *errMsg) { 1023 cli->sendMsg(ResponseCode::OperationFailed, errMsg, false); 1024} 1025 1026int CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 1027 if (argc < 2) { 1028 sendGenericSyntaxError(cli, "<cmds> <args...>"); 1029 return 0; 1030 } 1031 1032 ALOGV("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]); 1033 1034 if (!strcmp(argv[1], "enable")) { 1035 int rc = sBandwidthCtrl->enableBandwidthControl(true); 1036 sendGenericOkFail(cli, rc); 1037 return 0; 1038 1039 } 1040 if (!strcmp(argv[1], "disable")) { 1041 int rc = sBandwidthCtrl->disableBandwidthControl(); 1042 sendGenericOkFail(cli, rc); 1043 return 0; 1044 1045 } 1046 if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) { 1047 if (argc != 3) { 1048 sendGenericSyntaxError(cli, "removequota <interface>"); 1049 return 0; 1050 } 1051 int rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]); 1052 sendGenericOkFail(cli, rc); 1053 return 0; 1054 1055 } 1056 if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) { 1057 int64_t bytes; 1058 if (argc != 2) { 1059 sendGenericSyntaxError(cli, "getquota"); 1060 return 0; 1061 } 1062 int rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes); 1063 if (rc) { 1064 sendGenericOpFailed(cli, "Failed to get quota"); 1065 return 0; 1066 } 1067 1068 char *msg; 1069 asprintf(&msg, "%lld", bytes); 1070 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 1071 free(msg); 1072 return 0; 1073 1074 } 1075 if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) { 1076 int64_t bytes; 1077 if (argc != 3) { 1078 sendGenericSyntaxError(cli, "getiquota <iface>"); 1079 return 0; 1080 } 1081 1082 int rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes); 1083 if (rc) { 1084 sendGenericOpFailed(cli, "Failed to get quota"); 1085 return 0; 1086 } 1087 char *msg; 1088 asprintf(&msg, "%lld", bytes); 1089 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 1090 free(msg); 1091 return 0; 1092 1093 } 1094 if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) { 1095 if (argc != 4) { 1096 sendGenericSyntaxError(cli, "setquota <interface> <bytes>"); 1097 return 0; 1098 } 1099 int rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3])); 1100 sendGenericOkFail(cli, rc); 1101 return 0; 1102 } 1103 if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) { 1104 int rc; 1105 if (argc < 4) { 1106 sendGenericSyntaxError(cli, "setquotas <bytes> <interface> ..."); 1107 return 0; 1108 } 1109 1110 for (int q = 3; argc >= 4; q++, argc--) { 1111 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2])); 1112 if (rc) { 1113 char *msg; 1114 asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]); 1115 cli->sendMsg(ResponseCode::OperationFailed, 1116 msg, false); 1117 free(msg); 1118 return 0; 1119 } 1120 } 1121 sendGenericOkFail(cli, rc); 1122 return 0; 1123 1124 } 1125 if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) { 1126 int rc; 1127 if (argc < 3) { 1128 sendGenericSyntaxError(cli, "removequotas <interface> ..."); 1129 return 0; 1130 } 1131 1132 for (int q = 2; argc >= 3; q++, argc--) { 1133 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]); 1134 if (rc) { 1135 char *msg; 1136 asprintf(&msg, "bandwidth removequotas %s failed", argv[q]); 1137 cli->sendMsg(ResponseCode::OperationFailed, 1138 msg, false); 1139 free(msg); 1140 return 0; 1141 } 1142 } 1143 sendGenericOkFail(cli, rc); 1144 return 0; 1145 1146 } 1147 if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) { 1148 if (argc != 3) { 1149 sendGenericSyntaxError(cli, "removeiquota <interface>"); 1150 return 0; 1151 } 1152 int rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]); 1153 sendGenericOkFail(cli, rc); 1154 return 0; 1155 1156 } 1157 if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) { 1158 if (argc != 4) { 1159 sendGenericSyntaxError(cli, "setiquota <interface> <bytes>"); 1160 return 0; 1161 } 1162 int rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3])); 1163 sendGenericOkFail(cli, rc); 1164 return 0; 1165 1166 } 1167 if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) { 1168 if (argc < 3) { 1169 sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ..."); 1170 return 0; 1171 } 1172 int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2); 1173 sendGenericOkFail(cli, rc); 1174 return 0; 1175 1176 1177 } 1178 if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) { 1179 if (argc < 3) { 1180 sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ..."); 1181 return 0; 1182 } 1183 int rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2); 1184 sendGenericOkFail(cli, rc); 1185 return 0; 1186 1187 } 1188 if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) { 1189 if (argc != 3) { 1190 sendGenericSyntaxError(cli, "setglobalalert <bytes>"); 1191 return 0; 1192 } 1193 int rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2])); 1194 sendGenericOkFail(cli, rc); 1195 return 0; 1196 1197 } 1198 if (!strcmp(argv[1], "debugsettetherglobalalert") || !strcmp(argv[1], "dstga")) { 1199 if (argc != 4) { 1200 sendGenericSyntaxError(cli, "debugsettetherglobalalert <interface0> <interface1>"); 1201 return 0; 1202 } 1203 /* We ignore the interfaces for now. */ 1204 int rc = sBandwidthCtrl->setGlobalAlertInForwardChain(); 1205 sendGenericOkFail(cli, rc); 1206 return 0; 1207 1208 } 1209 if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) { 1210 if (argc != 2) { 1211 sendGenericSyntaxError(cli, "removeglobalalert"); 1212 return 0; 1213 } 1214 int rc = sBandwidthCtrl->removeGlobalAlert(); 1215 sendGenericOkFail(cli, rc); 1216 return 0; 1217 1218 } 1219 if (!strcmp(argv[1], "debugremovetetherglobalalert") || !strcmp(argv[1], "drtga")) { 1220 if (argc != 4) { 1221 sendGenericSyntaxError(cli, "debugremovetetherglobalalert <interface0> <interface1>"); 1222 return 0; 1223 } 1224 /* We ignore the interfaces for now. */ 1225 int rc = sBandwidthCtrl->removeGlobalAlertInForwardChain(); 1226 sendGenericOkFail(cli, rc); 1227 return 0; 1228 1229 } 1230 if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) { 1231 if (argc != 3) { 1232 sendGenericSyntaxError(cli, "setsharedalert <bytes>"); 1233 return 0; 1234 } 1235 int rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2])); 1236 sendGenericOkFail(cli, rc); 1237 return 0; 1238 1239 } 1240 if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) { 1241 if (argc != 2) { 1242 sendGenericSyntaxError(cli, "removesharedalert"); 1243 return 0; 1244 } 1245 int rc = sBandwidthCtrl->removeSharedAlert(); 1246 sendGenericOkFail(cli, rc); 1247 return 0; 1248 1249 } 1250 if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) { 1251 if (argc != 4) { 1252 sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>"); 1253 return 0; 1254 } 1255 int rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3])); 1256 sendGenericOkFail(cli, rc); 1257 return 0; 1258 1259 } 1260 if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) { 1261 if (argc != 3) { 1262 sendGenericSyntaxError(cli, "removeinterfacealert <interface>"); 1263 return 0; 1264 } 1265 int rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]); 1266 sendGenericOkFail(cli, rc); 1267 return 0; 1268 1269 } 1270 if (!strcmp(argv[1], "gettetherstats") || !strcmp(argv[1], "gts")) { 1271 BandwidthController::TetherStats tetherStats; 1272 std::string extraProcessingInfo = ""; 1273 if (argc != 4) { 1274 sendGenericSyntaxError(cli, "gettetherstats <interface0> <interface1>"); 1275 return 0; 1276 } 1277 1278 tetherStats.ifaceIn = argv[2]; 1279 tetherStats.ifaceOut = argv[3]; 1280 int rc = sBandwidthCtrl->getTetherStats(tetherStats, extraProcessingInfo); 1281 if (rc) { 1282 extraProcessingInfo.insert(0, "Failed to get tethering stats.\n"); 1283 sendGenericOpFailed(cli, extraProcessingInfo.c_str()); 1284 return 0; 1285 } 1286 1287 char *msg = tetherStats.getStatsLine(); 1288 cli->sendMsg(ResponseCode::TetheringStatsResult, msg, false); 1289 free(msg); 1290 return 0; 1291 1292 } 1293 1294 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false); 1295 return 0; 1296} 1297 1298CommandListener::IdletimerControlCmd::IdletimerControlCmd() : 1299 NetdCommand("idletimer") { 1300} 1301 1302int CommandListener::IdletimerControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 1303 // TODO(ashish): Change the error statements 1304 if (argc < 2) { 1305 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1306 return 0; 1307 } 1308 1309 ALOGV("idletimerctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]); 1310 1311 if (!strcmp(argv[1], "enable")) { 1312 if (0 != sIdletimerCtrl->enableIdletimerControl()) { 1313 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1314 } else { 1315 cli->sendMsg(ResponseCode::CommandOkay, "Enable success", false); 1316 } 1317 return 0; 1318 1319 } 1320 if (!strcmp(argv[1], "disable")) { 1321 if (0 != sIdletimerCtrl->disableIdletimerControl()) { 1322 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1323 } else { 1324 cli->sendMsg(ResponseCode::CommandOkay, "Disable success", false); 1325 } 1326 return 0; 1327 } 1328 if (!strcmp(argv[1], "add")) { 1329 if (argc != 5) { 1330 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1331 return 0; 1332 } 1333 if(0 != sIdletimerCtrl->addInterfaceIdletimer( 1334 argv[2], atoi(argv[3]), argv[4])) { 1335 cli->sendMsg(ResponseCode::OperationFailed, "Failed to add interface", false); 1336 } else { 1337 cli->sendMsg(ResponseCode::CommandOkay, "Add success", false); 1338 } 1339 return 0; 1340 } 1341 if (!strcmp(argv[1], "remove")) { 1342 if (argc != 5) { 1343 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1344 return 0; 1345 } 1346 // ashish: fixme timeout 1347 if (0 != sIdletimerCtrl->removeInterfaceIdletimer( 1348 argv[2], atoi(argv[3]), argv[4])) { 1349 cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove interface", false); 1350 } else { 1351 cli->sendMsg(ResponseCode::CommandOkay, "Remove success", false); 1352 } 1353 return 0; 1354 } 1355 1356 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown idletimer cmd", false); 1357 return 0; 1358} 1359 1360CommandListener::FirewallCmd::FirewallCmd() : 1361 NetdCommand("firewall") { 1362} 1363 1364int CommandListener::FirewallCmd::sendGenericOkFail(SocketClient *cli, int cond) { 1365 if (!cond) { 1366 cli->sendMsg(ResponseCode::CommandOkay, "Firewall command succeeded", false); 1367 } else { 1368 cli->sendMsg(ResponseCode::OperationFailed, "Firewall command failed", false); 1369 } 1370 return 0; 1371} 1372 1373FirewallRule CommandListener::FirewallCmd::parseRule(const char* arg) { 1374 if (!strcmp(arg, "allow")) { 1375 return ALLOW; 1376 } else { 1377 return DENY; 1378 } 1379} 1380 1381int CommandListener::FirewallCmd::runCommand(SocketClient *cli, int argc, 1382 char **argv) { 1383 if (argc < 2) { 1384 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false); 1385 return 0; 1386 } 1387 1388 if (!strcmp(argv[1], "enable")) { 1389 int res = sFirewallCtrl->enableFirewall(); 1390 return sendGenericOkFail(cli, res); 1391 } 1392 if (!strcmp(argv[1], "disable")) { 1393 int res = sFirewallCtrl->disableFirewall(); 1394 return sendGenericOkFail(cli, res); 1395 } 1396 if (!strcmp(argv[1], "is_enabled")) { 1397 int res = sFirewallCtrl->isFirewallEnabled(); 1398 return sendGenericOkFail(cli, res); 1399 } 1400 1401 if (!strcmp(argv[1], "set_interface_rule")) { 1402 if (argc != 4) { 1403 cli->sendMsg(ResponseCode::CommandSyntaxError, 1404 "Usage: firewall set_interface_rule <rmnet0> <allow|deny>", false); 1405 return 0; 1406 } 1407 1408 const char* iface = argv[2]; 1409 FirewallRule rule = parseRule(argv[3]); 1410 1411 int res = sFirewallCtrl->setInterfaceRule(iface, rule); 1412 return sendGenericOkFail(cli, res); 1413 } 1414 1415 if (!strcmp(argv[1], "set_egress_source_rule")) { 1416 if (argc != 4) { 1417 cli->sendMsg(ResponseCode::CommandSyntaxError, 1418 "Usage: firewall set_egress_source_rule <192.168.0.1> <allow|deny>", 1419 false); 1420 return 0; 1421 } 1422 1423 const char* addr = argv[2]; 1424 FirewallRule rule = parseRule(argv[3]); 1425 1426 int res = sFirewallCtrl->setEgressSourceRule(addr, rule); 1427 return sendGenericOkFail(cli, res); 1428 } 1429 1430 if (!strcmp(argv[1], "set_egress_dest_rule")) { 1431 if (argc != 5) { 1432 cli->sendMsg(ResponseCode::CommandSyntaxError, 1433 "Usage: firewall set_egress_dest_rule <192.168.0.1> <80> <allow|deny>", 1434 false); 1435 return 0; 1436 } 1437 1438 const char* addr = argv[2]; 1439 int port = atoi(argv[3]); 1440 FirewallRule rule = parseRule(argv[4]); 1441 1442 int res = 0; 1443 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_TCP, port, rule); 1444 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_UDP, port, rule); 1445 return sendGenericOkFail(cli, res); 1446 } 1447 1448 if (!strcmp(argv[1], "set_uid_rule")) { 1449 if (argc != 4) { 1450 cli->sendMsg(ResponseCode::CommandSyntaxError, 1451 "Usage: firewall set_uid_rule <1000> <allow|deny>", 1452 false); 1453 return 0; 1454 } 1455 1456 int uid = atoi(argv[2]); 1457 FirewallRule rule = parseRule(argv[3]); 1458 1459 int res = sFirewallCtrl->setUidRule(uid, rule); 1460 return sendGenericOkFail(cli, res); 1461 } 1462 1463 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false); 1464 return 0; 1465} 1466