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