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