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