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