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