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