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