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