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