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