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, "android.permission.CHANGE_NETWORK_STATE")) { 58 return PERMISSION_NETWORK; 59 } 60 if (!strcmp(arg, "android.permission.CONNECTIVITY_INTERNAL")) { 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; 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 */ 100static 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 108static 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 116static const char* FILTER_OUTPUT[] = { 117 OEM_IPTABLES_FILTER_OUTPUT, 118 FirewallController::LOCAL_OUTPUT, 119 BandwidthController::LOCAL_OUTPUT, 120 NULL, 121}; 122 123static const char* RAW_PREROUTING[] = { 124 BandwidthController::LOCAL_RAW_PREROUTING, 125 IdletimerController::LOCAL_RAW_PREROUTING, 126 NULL, 127}; 128 129static const char* MANGLE_POSTROUTING[] = { 130 BandwidthController::LOCAL_MANGLE_POSTROUTING, 131 IdletimerController::LOCAL_MANGLE_POSTROUTING, 132 NULL, 133}; 134 135static const char* MANGLE_FORWARD[] = { 136 NatController::LOCAL_MANGLE_FORWARD, 137 NULL, 138}; 139 140static const char* NAT_PREROUTING[] = { 141 OEM_IPTABLES_NAT_PREROUTING, 142 NULL, 143}; 144 145static const char* NAT_POSTROUTING[] = { 146 NatController::LOCAL_NAT_POSTROUTING, 147 NULL, 148}; 149 150static 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 170CommandListener::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 255CommandListener::InterfaceCmd::InterfaceCmd() : 256 NetdCommand("interface") { 257} 258 259int 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], "setmtu")) { 448 if (argc != 4) { 449 cli->sendMsg(ResponseCode::CommandSyntaxError, 450 "Usage: interface setmtu <interface> <val>", false); 451 return 0; 452 } 453 if (sInterfaceCtrl->setMtu(argv[2], argv[3]) == 0) { 454 cli->sendMsg(ResponseCode::CommandOkay, "MTU changed", false); 455 } else { 456 cli->sendMsg(ResponseCode::OperationFailed, 457 "Failed to get MTU", true); 458 } 459 return 0; 460 } else { 461 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 462 return 0; 463 } 464 } 465 return 0; 466} 467 468 469CommandListener::ListTtysCmd::ListTtysCmd() : 470 NetdCommand("list_ttys") { 471} 472 473int CommandListener::ListTtysCmd::runCommand(SocketClient *cli, 474 int /* argc */, char ** /* argv */) { 475 TtyCollection *tlist = sPppCtrl->getTtyList(); 476 TtyCollection::iterator it; 477 478 for (it = tlist->begin(); it != tlist->end(); ++it) { 479 cli->sendMsg(ResponseCode::TtyListResult, *it, false); 480 } 481 482 cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false); 483 return 0; 484} 485 486CommandListener::IpFwdCmd::IpFwdCmd() : 487 NetdCommand("ipfwd") { 488} 489 490int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 491 int argc, char **argv) { 492 int rc = 0; 493 494 if (argc < 2) { 495 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 496 return 0; 497 } 498 499 if (!strcmp(argv[1], "status")) { 500 char *tmp = NULL; 501 502 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 503 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 504 free(tmp); 505 return 0; 506 } else if (!strcmp(argv[1], "enable")) { 507 rc = sTetherCtrl->setIpFwdEnabled(true); 508 } else if (!strcmp(argv[1], "disable")) { 509 rc = sTetherCtrl->setIpFwdEnabled(false); 510 } else { 511 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 512 return 0; 513 } 514 515 if (!rc) { 516 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 517 } else { 518 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 519 } 520 521 return 0; 522} 523 524CommandListener::TetherCmd::TetherCmd() : 525 NetdCommand("tether") { 526} 527 528int CommandListener::TetherCmd::runCommand(SocketClient *cli, 529 int argc, char **argv) { 530 int rc = 0; 531 532 if (argc < 2) { 533 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 534 return 0; 535 } 536 537 if (!strcmp(argv[1], "stop")) { 538 rc = sTetherCtrl->stopTethering(); 539 } else if (!strcmp(argv[1], "status")) { 540 char *tmp = NULL; 541 542 asprintf(&tmp, "Tethering services %s", 543 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 544 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 545 free(tmp); 546 return 0; 547 } else if (argc == 3) { 548 if (!strcmp(argv[1], "interface") && !strcmp(argv[2], "list")) { 549 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 550 InterfaceCollection::iterator it; 551 for (it = ilist->begin(); it != ilist->end(); ++it) { 552 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 553 } 554 } else if (!strcmp(argv[1], "dns") && !strcmp(argv[2], "list")) { 555 char netIdStr[UINT32_STRLEN]; 556 snprintf(netIdStr, sizeof(netIdStr), "%u", sTetherCtrl->getDnsNetId()); 557 cli->sendMsg(ResponseCode::TetherDnsFwdNetIdResult, netIdStr, false); 558 559 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 560 NetAddressCollection::iterator it; 561 562 for (it = dlist->begin(); it != dlist->end(); ++it) { 563 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 564 } 565 } 566 } else { 567 /* 568 * These commands take a minimum of 4 arguments 569 */ 570 if (argc < 4) { 571 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 572 return 0; 573 } 574 575 if (!strcmp(argv[1], "start")) { 576 if (argc % 2 == 1) { 577 cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false); 578 return 0; 579 } 580 581 int num_addrs = argc - 2; 582 int arg_index = 2; 583 int array_index = 0; 584 in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs); 585 while (array_index < num_addrs) { 586 if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) { 587 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 588 free(addrs); 589 return 0; 590 } 591 } 592 rc = sTetherCtrl->startTethering(num_addrs, addrs); 593 free(addrs); 594 } else if (!strcmp(argv[1], "interface")) { 595 if (!strcmp(argv[2], "add")) { 596 rc = sTetherCtrl->tetherInterface(argv[3]); 597 } else if (!strcmp(argv[2], "remove")) { 598 rc = sTetherCtrl->untetherInterface(argv[3]); 599 /* else if (!strcmp(argv[2], "list")) handled above */ 600 } else { 601 cli->sendMsg(ResponseCode::CommandParameterError, 602 "Unknown tether interface operation", false); 603 return 0; 604 } 605 } else if (!strcmp(argv[1], "dns")) { 606 if (!strcmp(argv[2], "set")) { 607 if (argc < 5) { 608 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 609 return 0; 610 } 611 unsigned netId = stringToNetId(argv[3]); 612 rc = sTetherCtrl->setDnsForwarders(netId, &argv[4], argc - 4); 613 /* else if (!strcmp(argv[2], "list")) handled above */ 614 } else { 615 cli->sendMsg(ResponseCode::CommandParameterError, 616 "Unknown tether interface operation", false); 617 return 0; 618 } 619 } else { 620 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 621 return 0; 622 } 623 } 624 625 if (!rc) { 626 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 627 } else { 628 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 629 } 630 631 return 0; 632} 633 634CommandListener::NatCmd::NatCmd() : 635 NetdCommand("nat") { 636} 637 638int CommandListener::NatCmd::runCommand(SocketClient *cli, 639 int argc, char **argv) { 640 int rc = 0; 641 642 if (argc < 5) { 643 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 644 return 0; 645 } 646 647 // 0 1 2 3 648 // nat enable intiface extiface 649 // nat disable intiface extiface 650 if (!strcmp(argv[1], "enable") && argc >= 4) { 651 rc = sNatCtrl->enableNat(argv[2], argv[3]); 652 if(!rc) { 653 /* Ignore ifaces for now. */ 654 rc = sBandwidthCtrl->setGlobalAlertInForwardChain(); 655 } 656 } else if (!strcmp(argv[1], "disable") && argc >= 4) { 657 /* Ignore ifaces for now. */ 658 rc = sBandwidthCtrl->removeGlobalAlertInForwardChain(); 659 rc |= sNatCtrl->disableNat(argv[2], argv[3]); 660 } else { 661 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 662 return 0; 663 } 664 665 if (!rc) { 666 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 667 } else { 668 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 669 } 670 671 return 0; 672} 673 674CommandListener::PppdCmd::PppdCmd() : 675 NetdCommand("pppd") { 676} 677 678int CommandListener::PppdCmd::runCommand(SocketClient *cli, 679 int argc, char **argv) { 680 int rc = 0; 681 682 if (argc < 3) { 683 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 684 return 0; 685 } 686 687 if (!strcmp(argv[1], "attach")) { 688 struct in_addr l, r, dns1, dns2; 689 690 memset(&dns1, 0, sizeof(struct in_addr)); 691 memset(&dns2, 0, sizeof(struct in_addr)); 692 693 if (!inet_aton(argv[3], &l)) { 694 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false); 695 return 0; 696 } 697 if (!inet_aton(argv[4], &r)) { 698 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false); 699 return 0; 700 } 701 if ((argc > 3) && (!inet_aton(argv[5], &dns1))) { 702 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false); 703 return 0; 704 } 705 if ((argc > 4) && (!inet_aton(argv[6], &dns2))) { 706 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false); 707 return 0; 708 } 709 rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2); 710 } else if (!strcmp(argv[1], "detach")) { 711 rc = sPppCtrl->detachPppd(argv[2]); 712 } else { 713 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false); 714 return 0; 715 } 716 717 if (!rc) { 718 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false); 719 } else { 720 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true); 721 } 722 723 return 0; 724} 725 726CommandListener::SoftapCmd::SoftapCmd() : 727 NetdCommand("softap") { 728} 729 730int CommandListener::SoftapCmd::runCommand(SocketClient *cli, 731 int argc, char **argv) { 732 int rc = ResponseCode::SoftapStatusResult; 733 char *retbuf = NULL; 734 735 if (sSoftapCtrl == NULL) { 736 cli->sendMsg(ResponseCode::ServiceStartFailed, "SoftAP is not available", false); 737 return -1; 738 } 739 if (argc < 2) { 740 cli->sendMsg(ResponseCode::CommandSyntaxError, 741 "Missing argument in a SoftAP command", false); 742 return 0; 743 } 744 745 if (!strcmp(argv[1], "startap")) { 746 rc = sSoftapCtrl->startSoftap(); 747 } else if (!strcmp(argv[1], "stopap")) { 748 rc = sSoftapCtrl->stopSoftap(); 749 } else if (!strcmp(argv[1], "fwreload")) { 750 rc = sSoftapCtrl->fwReloadSoftap(argc, argv); 751 } else if (!strcmp(argv[1], "status")) { 752 asprintf(&retbuf, "Softap service %s running", 753 (sSoftapCtrl->isSoftapStarted() ? "is" : "is not")); 754 cli->sendMsg(rc, retbuf, false); 755 free(retbuf); 756 return 0; 757 } else if (!strcmp(argv[1], "set")) { 758 rc = sSoftapCtrl->setSoftap(argc, argv); 759 } else { 760 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unrecognized SoftAP command", false); 761 return 0; 762 } 763 764 if (rc >= 400 && rc < 600) 765 cli->sendMsg(rc, "SoftAP command has failed", false); 766 else 767 cli->sendMsg(rc, "Ok", false); 768 769 return 0; 770} 771 772CommandListener::ResolverCmd::ResolverCmd() : 773 NetdCommand("resolver") { 774} 775 776int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **margv) { 777 int rc = 0; 778 const char **argv = const_cast<const char **>(margv); 779 780 if (argc < 2) { 781 cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false); 782 return 0; 783 } 784 785 if (!strcmp(argv[1], "setnetdns")) { 786 // "resolver setnetdns <netId> <domains> <dns1> <dns2> ..." 787 if (argc >= 5) { 788 rc = sResolverCtrl->setDnsServers(strtoul(argv[2], NULL, 0), argv[3], &argv[4], argc - 4); 789 } else { 790 cli->sendMsg(ResponseCode::CommandSyntaxError, 791 "Wrong number of arguments to resolver setnetdns", false); 792 return 0; 793 } 794 } else if (!strcmp(argv[1], "flushnet")) { // "resolver flushnet <netId>" 795 if (argc == 3) { 796 rc = sResolverCtrl->flushDnsCache(strtoul(argv[2], NULL, 0)); 797 } else { 798 cli->sendMsg(ResponseCode::CommandSyntaxError, 799 "Wrong number of arguments to resolver flushnet", false); 800 return 0; 801 } 802 } else { 803 cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false); 804 return 0; 805 } 806 807 if (!rc) { 808 cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false); 809 } else { 810 cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true); 811 } 812 813 return 0; 814} 815 816CommandListener::BandwidthControlCmd::BandwidthControlCmd() : 817 NetdCommand("bandwidth") { 818} 819 820void CommandListener::BandwidthControlCmd::sendGenericSyntaxError(SocketClient *cli, const char *usageMsg) { 821 char *msg; 822 asprintf(&msg, "Usage: bandwidth %s", usageMsg); 823 cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false); 824 free(msg); 825} 826 827void CommandListener::BandwidthControlCmd::sendGenericOkFail(SocketClient *cli, int cond) { 828 if (!cond) { 829 cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false); 830 } else { 831 cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false); 832 } 833} 834 835void CommandListener::BandwidthControlCmd::sendGenericOpFailed(SocketClient *cli, const char *errMsg) { 836 cli->sendMsg(ResponseCode::OperationFailed, errMsg, false); 837} 838 839int CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 840 if (argc < 2) { 841 sendGenericSyntaxError(cli, "<cmds> <args...>"); 842 return 0; 843 } 844 845 ALOGV("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]); 846 847 if (!strcmp(argv[1], "enable")) { 848 int rc = sBandwidthCtrl->enableBandwidthControl(true); 849 sendGenericOkFail(cli, rc); 850 return 0; 851 852 } 853 if (!strcmp(argv[1], "disable")) { 854 int rc = sBandwidthCtrl->disableBandwidthControl(); 855 sendGenericOkFail(cli, rc); 856 return 0; 857 858 } 859 if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) { 860 if (argc != 3) { 861 sendGenericSyntaxError(cli, "removequota <interface>"); 862 return 0; 863 } 864 int rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]); 865 sendGenericOkFail(cli, rc); 866 return 0; 867 868 } 869 if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) { 870 int64_t bytes; 871 if (argc != 2) { 872 sendGenericSyntaxError(cli, "getquota"); 873 return 0; 874 } 875 int rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes); 876 if (rc) { 877 sendGenericOpFailed(cli, "Failed to get quota"); 878 return 0; 879 } 880 881 char *msg; 882 asprintf(&msg, "%" PRId64, bytes); 883 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 884 free(msg); 885 return 0; 886 887 } 888 if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) { 889 int64_t bytes; 890 if (argc != 3) { 891 sendGenericSyntaxError(cli, "getiquota <iface>"); 892 return 0; 893 } 894 895 int rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes); 896 if (rc) { 897 sendGenericOpFailed(cli, "Failed to get quota"); 898 return 0; 899 } 900 char *msg; 901 asprintf(&msg, "%" PRId64, bytes); 902 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 903 free(msg); 904 return 0; 905 906 } 907 if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) { 908 if (argc != 4) { 909 sendGenericSyntaxError(cli, "setquota <interface> <bytes>"); 910 return 0; 911 } 912 int rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3])); 913 sendGenericOkFail(cli, rc); 914 return 0; 915 } 916 if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) { 917 int rc; 918 if (argc < 4) { 919 sendGenericSyntaxError(cli, "setquotas <bytes> <interface> ..."); 920 return 0; 921 } 922 923 for (int q = 3; argc >= 4; q++, argc--) { 924 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2])); 925 if (rc) { 926 char *msg; 927 asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]); 928 cli->sendMsg(ResponseCode::OperationFailed, 929 msg, false); 930 free(msg); 931 return 0; 932 } 933 } 934 sendGenericOkFail(cli, rc); 935 return 0; 936 937 } 938 if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) { 939 int rc; 940 if (argc < 3) { 941 sendGenericSyntaxError(cli, "removequotas <interface> ..."); 942 return 0; 943 } 944 945 for (int q = 2; argc >= 3; q++, argc--) { 946 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]); 947 if (rc) { 948 char *msg; 949 asprintf(&msg, "bandwidth removequotas %s failed", argv[q]); 950 cli->sendMsg(ResponseCode::OperationFailed, 951 msg, false); 952 free(msg); 953 return 0; 954 } 955 } 956 sendGenericOkFail(cli, rc); 957 return 0; 958 959 } 960 if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) { 961 if (argc != 3) { 962 sendGenericSyntaxError(cli, "removeiquota <interface>"); 963 return 0; 964 } 965 int rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]); 966 sendGenericOkFail(cli, rc); 967 return 0; 968 969 } 970 if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) { 971 if (argc != 4) { 972 sendGenericSyntaxError(cli, "setiquota <interface> <bytes>"); 973 return 0; 974 } 975 int rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3])); 976 sendGenericOkFail(cli, rc); 977 return 0; 978 979 } 980 if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) { 981 if (argc < 3) { 982 sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ..."); 983 return 0; 984 } 985 int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2); 986 sendGenericOkFail(cli, rc); 987 return 0; 988 989 990 } 991 if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) { 992 if (argc < 3) { 993 sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ..."); 994 return 0; 995 } 996 int rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2); 997 sendGenericOkFail(cli, rc); 998 return 0; 999 } 1000 if (!strcmp(argv[1], "happybox")) { 1001 if (argc < 3) { 1002 sendGenericSyntaxError(cli, "happybox (enable | disable)"); 1003 return 0; 1004 } 1005 if (!strcmp(argv[2], "enable")) { 1006 int rc = sBandwidthCtrl->enableHappyBox(); 1007 sendGenericOkFail(cli, rc); 1008 return 0; 1009 1010 } 1011 if (!strcmp(argv[2], "disable")) { 1012 int rc = sBandwidthCtrl->disableHappyBox(); 1013 sendGenericOkFail(cli, rc); 1014 return 0; 1015 } 1016 sendGenericSyntaxError(cli, "happybox (enable | disable)"); 1017 return 0; 1018 } 1019 if (!strcmp(argv[1], "addniceapps") || !strcmp(argv[1], "aha")) { 1020 if (argc < 3) { 1021 sendGenericSyntaxError(cli, "addniceapps <appUid> ..."); 1022 return 0; 1023 } 1024 int rc = sBandwidthCtrl->addNiceApps(argc - 2, argv + 2); 1025 sendGenericOkFail(cli, rc); 1026 return 0; 1027 } 1028 if (!strcmp(argv[1], "removeniceapps") || !strcmp(argv[1], "rha")) { 1029 if (argc < 3) { 1030 sendGenericSyntaxError(cli, "removeniceapps <appUid> ..."); 1031 return 0; 1032 } 1033 int rc = sBandwidthCtrl->removeNiceApps(argc - 2, argv + 2); 1034 sendGenericOkFail(cli, rc); 1035 return 0; 1036 } 1037 if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) { 1038 if (argc != 3) { 1039 sendGenericSyntaxError(cli, "setglobalalert <bytes>"); 1040 return 0; 1041 } 1042 int rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2])); 1043 sendGenericOkFail(cli, rc); 1044 return 0; 1045 } 1046 if (!strcmp(argv[1], "debugsettetherglobalalert") || !strcmp(argv[1], "dstga")) { 1047 if (argc != 4) { 1048 sendGenericSyntaxError(cli, "debugsettetherglobalalert <interface0> <interface1>"); 1049 return 0; 1050 } 1051 /* We ignore the interfaces for now. */ 1052 int rc = sBandwidthCtrl->setGlobalAlertInForwardChain(); 1053 sendGenericOkFail(cli, rc); 1054 return 0; 1055 1056 } 1057 if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) { 1058 if (argc != 2) { 1059 sendGenericSyntaxError(cli, "removeglobalalert"); 1060 return 0; 1061 } 1062 int rc = sBandwidthCtrl->removeGlobalAlert(); 1063 sendGenericOkFail(cli, rc); 1064 return 0; 1065 1066 } 1067 if (!strcmp(argv[1], "debugremovetetherglobalalert") || !strcmp(argv[1], "drtga")) { 1068 if (argc != 4) { 1069 sendGenericSyntaxError(cli, "debugremovetetherglobalalert <interface0> <interface1>"); 1070 return 0; 1071 } 1072 /* We ignore the interfaces for now. */ 1073 int rc = sBandwidthCtrl->removeGlobalAlertInForwardChain(); 1074 sendGenericOkFail(cli, rc); 1075 return 0; 1076 1077 } 1078 if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) { 1079 if (argc != 3) { 1080 sendGenericSyntaxError(cli, "setsharedalert <bytes>"); 1081 return 0; 1082 } 1083 int rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2])); 1084 sendGenericOkFail(cli, rc); 1085 return 0; 1086 1087 } 1088 if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) { 1089 if (argc != 2) { 1090 sendGenericSyntaxError(cli, "removesharedalert"); 1091 return 0; 1092 } 1093 int rc = sBandwidthCtrl->removeSharedAlert(); 1094 sendGenericOkFail(cli, rc); 1095 return 0; 1096 1097 } 1098 if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) { 1099 if (argc != 4) { 1100 sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>"); 1101 return 0; 1102 } 1103 int rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3])); 1104 sendGenericOkFail(cli, rc); 1105 return 0; 1106 1107 } 1108 if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) { 1109 if (argc != 3) { 1110 sendGenericSyntaxError(cli, "removeinterfacealert <interface>"); 1111 return 0; 1112 } 1113 int rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]); 1114 sendGenericOkFail(cli, rc); 1115 return 0; 1116 1117 } 1118 if (!strcmp(argv[1], "gettetherstats") || !strcmp(argv[1], "gts")) { 1119 BandwidthController::TetherStats tetherStats; 1120 std::string extraProcessingInfo = ""; 1121 if (argc < 2 || argc > 4) { 1122 sendGenericSyntaxError(cli, "gettetherstats [<intInterface> <extInterface>]"); 1123 return 0; 1124 } 1125 tetherStats.intIface = argc > 2 ? argv[2] : ""; 1126 tetherStats.extIface = argc > 3 ? argv[3] : ""; 1127 // No filtering requested and there are no interface pairs to lookup. 1128 if (argc <= 2 && sNatCtrl->ifacePairList.empty()) { 1129 cli->sendMsg(ResponseCode::CommandOkay, "Tethering stats list completed", false); 1130 return 0; 1131 } 1132 int rc = sBandwidthCtrl->getTetherStats(cli, tetherStats, extraProcessingInfo); 1133 if (rc) { 1134 extraProcessingInfo.insert(0, "Failed to get tethering stats.\n"); 1135 sendGenericOpFailed(cli, extraProcessingInfo.c_str()); 1136 return 0; 1137 } 1138 return 0; 1139 1140 } 1141 1142 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false); 1143 return 0; 1144} 1145 1146CommandListener::IdletimerControlCmd::IdletimerControlCmd() : 1147 NetdCommand("idletimer") { 1148} 1149 1150int CommandListener::IdletimerControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 1151 // TODO(ashish): Change the error statements 1152 if (argc < 2) { 1153 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1154 return 0; 1155 } 1156 1157 ALOGV("idletimerctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]); 1158 1159 if (!strcmp(argv[1], "enable")) { 1160 if (0 != sIdletimerCtrl->enableIdletimerControl()) { 1161 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1162 } else { 1163 cli->sendMsg(ResponseCode::CommandOkay, "Enable success", false); 1164 } 1165 return 0; 1166 1167 } 1168 if (!strcmp(argv[1], "disable")) { 1169 if (0 != sIdletimerCtrl->disableIdletimerControl()) { 1170 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1171 } else { 1172 cli->sendMsg(ResponseCode::CommandOkay, "Disable success", false); 1173 } 1174 return 0; 1175 } 1176 if (!strcmp(argv[1], "add")) { 1177 if (argc != 5) { 1178 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1179 return 0; 1180 } 1181 if(0 != sIdletimerCtrl->addInterfaceIdletimer( 1182 argv[2], atoi(argv[3]), argv[4])) { 1183 cli->sendMsg(ResponseCode::OperationFailed, "Failed to add interface", false); 1184 } else { 1185 cli->sendMsg(ResponseCode::CommandOkay, "Add success", false); 1186 } 1187 return 0; 1188 } 1189 if (!strcmp(argv[1], "remove")) { 1190 if (argc != 5) { 1191 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1192 return 0; 1193 } 1194 // ashish: fixme timeout 1195 if (0 != sIdletimerCtrl->removeInterfaceIdletimer( 1196 argv[2], atoi(argv[3]), argv[4])) { 1197 cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove interface", false); 1198 } else { 1199 cli->sendMsg(ResponseCode::CommandOkay, "Remove success", false); 1200 } 1201 return 0; 1202 } 1203 1204 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown idletimer cmd", false); 1205 return 0; 1206} 1207 1208CommandListener::FirewallCmd::FirewallCmd() : 1209 NetdCommand("firewall") { 1210} 1211 1212int CommandListener::FirewallCmd::sendGenericOkFail(SocketClient *cli, int cond) { 1213 if (!cond) { 1214 cli->sendMsg(ResponseCode::CommandOkay, "Firewall command succeeded", false); 1215 } else { 1216 cli->sendMsg(ResponseCode::OperationFailed, "Firewall command failed", false); 1217 } 1218 return 0; 1219} 1220 1221FirewallRule CommandListener::FirewallCmd::parseRule(const char* arg) { 1222 if (!strcmp(arg, "allow")) { 1223 return ALLOW; 1224 } else { 1225 return DENY; 1226 } 1227} 1228 1229int CommandListener::FirewallCmd::runCommand(SocketClient *cli, int argc, 1230 char **argv) { 1231 if (argc < 2) { 1232 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false); 1233 return 0; 1234 } 1235 1236 if (!strcmp(argv[1], "enable")) { 1237 int res = sFirewallCtrl->enableFirewall(); 1238 return sendGenericOkFail(cli, res); 1239 } 1240 if (!strcmp(argv[1], "disable")) { 1241 int res = sFirewallCtrl->disableFirewall(); 1242 return sendGenericOkFail(cli, res); 1243 } 1244 if (!strcmp(argv[1], "is_enabled")) { 1245 int res = sFirewallCtrl->isFirewallEnabled(); 1246 return sendGenericOkFail(cli, res); 1247 } 1248 1249 if (!strcmp(argv[1], "set_interface_rule")) { 1250 if (argc != 4) { 1251 cli->sendMsg(ResponseCode::CommandSyntaxError, 1252 "Usage: firewall set_interface_rule <rmnet0> <allow|deny>", false); 1253 return 0; 1254 } 1255 1256 const char* iface = argv[2]; 1257 FirewallRule rule = parseRule(argv[3]); 1258 1259 int res = sFirewallCtrl->setInterfaceRule(iface, rule); 1260 return sendGenericOkFail(cli, res); 1261 } 1262 1263 if (!strcmp(argv[1], "set_egress_source_rule")) { 1264 if (argc != 4) { 1265 cli->sendMsg(ResponseCode::CommandSyntaxError, 1266 "Usage: firewall set_egress_source_rule <192.168.0.1> <allow|deny>", 1267 false); 1268 return 0; 1269 } 1270 1271 const char* addr = argv[2]; 1272 FirewallRule rule = parseRule(argv[3]); 1273 1274 int res = sFirewallCtrl->setEgressSourceRule(addr, rule); 1275 return sendGenericOkFail(cli, res); 1276 } 1277 1278 if (!strcmp(argv[1], "set_egress_dest_rule")) { 1279 if (argc != 5) { 1280 cli->sendMsg(ResponseCode::CommandSyntaxError, 1281 "Usage: firewall set_egress_dest_rule <192.168.0.1> <80> <allow|deny>", 1282 false); 1283 return 0; 1284 } 1285 1286 const char* addr = argv[2]; 1287 int port = atoi(argv[3]); 1288 FirewallRule rule = parseRule(argv[4]); 1289 1290 int res = 0; 1291 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_TCP, port, rule); 1292 res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_UDP, port, rule); 1293 return sendGenericOkFail(cli, res); 1294 } 1295 1296 if (!strcmp(argv[1], "set_uid_rule")) { 1297 if (argc != 4) { 1298 cli->sendMsg(ResponseCode::CommandSyntaxError, 1299 "Usage: firewall set_uid_rule <1000> <allow|deny>", 1300 false); 1301 return 0; 1302 } 1303 1304 int uid = atoi(argv[2]); 1305 FirewallRule rule = parseRule(argv[3]); 1306 1307 int res = sFirewallCtrl->setUidRule(uid, rule); 1308 return sendGenericOkFail(cli, res); 1309 } 1310 1311 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false); 1312 return 0; 1313} 1314 1315CommandListener::ClatdCmd::ClatdCmd() : NetdCommand("clatd") { 1316} 1317 1318int CommandListener::ClatdCmd::runCommand(SocketClient *cli, int argc, 1319 char **argv) { 1320 int rc = 0; 1321 if (argc < 2) { 1322 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1323 return 0; 1324 } 1325 1326 if(!strcmp(argv[1], "stop")) { 1327 rc = sClatdCtrl->stopClatd(); 1328 } else if (!strcmp(argv[1], "status")) { 1329 char *tmp = NULL; 1330 1331 asprintf(&tmp, "Clatd status: %s", (sClatdCtrl->isClatdStarted() ? 1332 "started" : "stopped")); 1333 cli->sendMsg(ResponseCode::ClatdStatusResult, tmp, false); 1334 free(tmp); 1335 return 0; 1336 } else if(!strcmp(argv[1], "start")) { 1337 if (argc < 3) { 1338 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 1339 return 0; 1340 } 1341 rc = sClatdCtrl->startClatd(argv[2]); 1342 } else { 1343 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown clatd cmd", false); 1344 return 0; 1345 } 1346 1347 if (!rc) { 1348 cli->sendMsg(ResponseCode::CommandOkay, "Clatd operation succeeded", false); 1349 } else { 1350 cli->sendMsg(ResponseCode::OperationFailed, "Clatd operation failed", false); 1351 } 1352 1353 return 0; 1354} 1355 1356CommandListener::NetworkCommand::NetworkCommand() : NetdCommand("network") { 1357} 1358 1359int CommandListener::NetworkCommand::syntaxError(SocketClient* client, const char* message) { 1360 client->sendMsg(ResponseCode::CommandSyntaxError, message, false); 1361 return 0; 1362} 1363 1364int CommandListener::NetworkCommand::operationError(SocketClient* client, const char* message, 1365 int ret) { 1366 errno = -ret; 1367 client->sendMsg(ResponseCode::OperationFailed, message, true); 1368 return 0; 1369} 1370 1371int CommandListener::NetworkCommand::success(SocketClient* client) { 1372 client->sendMsg(ResponseCode::CommandOkay, "success", false); 1373 return 0; 1374} 1375 1376int CommandListener::NetworkCommand::runCommand(SocketClient* client, int argc, char** argv) { 1377 if (argc < 2) { 1378 return syntaxError(client, "Missing argument"); 1379 } 1380 1381 // 0 1 2 3 4 5 6 7 8 1382 // network route [legacy <uid>] add <netId> <interface> <destination> [nexthop] 1383 // network route [legacy <uid>] remove <netId> <interface> <destination> [nexthop] 1384 // 1385 // nexthop may be either an IPv4/IPv6 address or one of "unreachable" or "throw". 1386 if (!strcmp(argv[1], "route")) { 1387 if (argc < 6 || argc > 9) { 1388 return syntaxError(client, "Incorrect number of arguments"); 1389 } 1390 1391 int nextArg = 2; 1392 bool legacy = false; 1393 uid_t uid = 0; 1394 if (!strcmp(argv[nextArg], "legacy")) { 1395 ++nextArg; 1396 legacy = true; 1397 uid = strtoul(argv[nextArg++], NULL, 0); 1398 } 1399 1400 bool add = false; 1401 if (!strcmp(argv[nextArg], "add")) { 1402 add = true; 1403 } else if (strcmp(argv[nextArg], "remove")) { 1404 return syntaxError(client, "Unknown argument"); 1405 } 1406 ++nextArg; 1407 1408 if (argc < nextArg + 3 || argc > nextArg + 4) { 1409 return syntaxError(client, "Incorrect number of arguments"); 1410 } 1411 1412 unsigned netId = stringToNetId(argv[nextArg++]); 1413 const char* interface = argv[nextArg++]; 1414 const char* destination = argv[nextArg++]; 1415 const char* nexthop = argc > nextArg ? argv[nextArg] : NULL; 1416 1417 int ret; 1418 if (add) { 1419 ret = sNetCtrl->addRoute(netId, interface, destination, nexthop, legacy, uid); 1420 } else { 1421 ret = sNetCtrl->removeRoute(netId, interface, destination, nexthop, legacy, uid); 1422 } 1423 if (ret) { 1424 return operationError(client, add ? "addRoute() failed" : "removeRoute() failed", ret); 1425 } 1426 1427 return success(client); 1428 } 1429 1430 // 0 1 2 3 4 1431 // network interface add <netId> <interface> 1432 // network interface remove <netId> <interface> 1433 if (!strcmp(argv[1], "interface")) { 1434 if (argc != 5) { 1435 return syntaxError(client, "Missing argument"); 1436 } 1437 unsigned netId = stringToNetId(argv[3]); 1438 if (!strcmp(argv[2], "add")) { 1439 if (int ret = sNetCtrl->addInterfaceToNetwork(netId, argv[4])) { 1440 return operationError(client, "addInterfaceToNetwork() failed", ret); 1441 } 1442 } else if (!strcmp(argv[2], "remove")) { 1443 if (int ret = sNetCtrl->removeInterfaceFromNetwork(netId, argv[4])) { 1444 return operationError(client, "removeInterfaceFromNetwork() failed", ret); 1445 } 1446 } else { 1447 return syntaxError(client, "Unknown argument"); 1448 } 1449 return success(client); 1450 } 1451 1452 // 0 1 2 3 1453 // network create <netId> [permission] 1454 // 1455 // 0 1 2 3 4 5 1456 // network create <netId> vpn <hasDns> <secure> 1457 if (!strcmp(argv[1], "create")) { 1458 if (argc < 3) { 1459 return syntaxError(client, "Missing argument"); 1460 } 1461 unsigned netId = stringToNetId(argv[2]); 1462 if (argc == 6 && !strcmp(argv[3], "vpn")) { 1463 bool hasDns = atoi(argv[4]); 1464 bool secure = atoi(argv[5]); 1465 if (int ret = sNetCtrl->createVirtualNetwork(netId, hasDns, secure)) { 1466 return operationError(client, "createVirtualNetwork() failed", ret); 1467 } 1468 } else if (argc > 4) { 1469 return syntaxError(client, "Unknown trailing argument(s)"); 1470 } else { 1471 Permission permission = PERMISSION_NONE; 1472 if (argc == 4) { 1473 permission = stringToPermission(argv[3]); 1474 if (permission == PERMISSION_NONE) { 1475 return syntaxError(client, "Unknown permission"); 1476 } 1477 } 1478 if (int ret = sNetCtrl->createPhysicalNetwork(netId, permission)) { 1479 return operationError(client, "createPhysicalNetwork() failed", ret); 1480 } 1481 } 1482 return success(client); 1483 } 1484 1485 // 0 1 2 1486 // network destroy <netId> 1487 if (!strcmp(argv[1], "destroy")) { 1488 if (argc != 3) { 1489 return syntaxError(client, "Incorrect number of arguments"); 1490 } 1491 unsigned netId = stringToNetId(argv[2]); 1492 if (int ret = sNetCtrl->destroyNetwork(netId)) { 1493 return operationError(client, "destroyNetwork() failed", ret); 1494 } 1495 return success(client); 1496 } 1497 1498 // 0 1 2 3 1499 // network default set <netId> 1500 // network default clear 1501 if (!strcmp(argv[1], "default")) { 1502 if (argc < 3) { 1503 return syntaxError(client, "Missing argument"); 1504 } 1505 unsigned netId = NETID_UNSET; 1506 if (!strcmp(argv[2], "set")) { 1507 if (argc < 4) { 1508 return syntaxError(client, "Missing netId"); 1509 } 1510 netId = stringToNetId(argv[3]); 1511 } else if (strcmp(argv[2], "clear")) { 1512 return syntaxError(client, "Unknown argument"); 1513 } 1514 if (int ret = sNetCtrl->setDefaultNetwork(netId)) { 1515 return operationError(client, "setDefaultNetwork() failed", ret); 1516 } 1517 return success(client); 1518 } 1519 1520 // 0 1 2 3 4 5 1521 // network permission user set <permission> <uid> ... 1522 // network permission user clear <uid> ... 1523 // network permission network set <permission> <netId> ... 1524 // network permission network clear <netId> ... 1525 if (!strcmp(argv[1], "permission")) { 1526 if (argc < 5) { 1527 return syntaxError(client, "Missing argument"); 1528 } 1529 int nextArg = 4; 1530 Permission permission = PERMISSION_NONE; 1531 if (!strcmp(argv[3], "set")) { 1532 permission = stringToPermission(argv[4]); 1533 if (permission == PERMISSION_NONE) { 1534 return syntaxError(client, "Unknown permission"); 1535 } 1536 nextArg = 5; 1537 } else if (strcmp(argv[3], "clear")) { 1538 return syntaxError(client, "Unknown argument"); 1539 } 1540 if (nextArg == argc) { 1541 return syntaxError(client, "Missing id"); 1542 } 1543 std::vector<unsigned> ids; 1544 for (; nextArg < argc; ++nextArg) { 1545 char* endPtr; 1546 unsigned id = strtoul(argv[nextArg], &endPtr, 0); 1547 if (!*argv[nextArg] || *endPtr) { 1548 return syntaxError(client, "Invalid id"); 1549 } 1550 ids.push_back(id); 1551 } 1552 if (!strcmp(argv[2], "user")) { 1553 sNetCtrl->setPermissionForUsers(permission, ids); 1554 } else if (!strcmp(argv[2], "network")) { 1555 if (int ret = sNetCtrl->setPermissionForNetworks(permission, ids)) { 1556 return operationError(client, "setPermissionForNetworks() failed", ret); 1557 } 1558 } else { 1559 return syntaxError(client, "Unknown argument"); 1560 } 1561 return success(client); 1562 } 1563 1564 // 0 1 2 3 4 1565 // network users add <netId> [<uid>[-<uid>]] ... 1566 // network users remove <netId> [<uid>[-<uid>]] ... 1567 if (!strcmp(argv[1], "users")) { 1568 if (argc < 4) { 1569 return syntaxError(client, "Missing argument"); 1570 } 1571 unsigned netId = stringToNetId(argv[3]); 1572 UidRanges uidRanges; 1573 if (!uidRanges.parseFrom(argc - 4, argv + 4)) { 1574 return syntaxError(client, "Invalid UIDs"); 1575 } 1576 if (!strcmp(argv[2], "add")) { 1577 if (int ret = sNetCtrl->addUsersToNetwork(netId, uidRanges)) { 1578 return operationError(client, "addUsersToNetwork() failed", ret); 1579 } 1580 } else if (!strcmp(argv[2], "remove")) { 1581 if (int ret = sNetCtrl->removeUsersFromNetwork(netId, uidRanges)) { 1582 return operationError(client, "removeUsersFromNetwork() failed", ret); 1583 } 1584 } else { 1585 return syntaxError(client, "Unknown argument"); 1586 } 1587 return success(client); 1588 } 1589 1590 // 0 1 2 3 1591 // network protect allow <uid> ... 1592 // network protect deny <uid> ... 1593 if (!strcmp(argv[1], "protect")) { 1594 if (argc < 4) { 1595 return syntaxError(client, "Missing argument"); 1596 } 1597 std::vector<uid_t> uids; 1598 for (int i = 3; i < argc; ++i) { 1599 uids.push_back(strtoul(argv[i], NULL, 0)); 1600 } 1601 if (!strcmp(argv[2], "allow")) { 1602 sNetCtrl->allowProtect(uids); 1603 } else if (!strcmp(argv[2], "deny")) { 1604 sNetCtrl->denyProtect(uids); 1605 } else { 1606 return syntaxError(client, "Unknown argument"); 1607 } 1608 return success(client); 1609 } 1610 1611 return syntaxError(client, "Unknown argument"); 1612} 1613