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