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