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