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