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