CommandListener.cpp revision 32a9dc6f484deb3462d11084caca21e3f1f662b2
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#include <stdlib.h> 18#include <sys/socket.h> 19#include <sys/types.h> 20#include <netinet/in.h> 21#include <arpa/inet.h> 22#include <dirent.h> 23#include <errno.h> 24#include <string.h> 25#include <fcntl.h> 26 27#include <linux/if.h> 28 29#define LOG_TAG "CommandListener" 30#include <cutils/log.h> 31 32#include <sysutils/SocketClient.h> 33 34#include "CommandListener.h" 35#include "ResponseCode.h" 36#include "ThrottleController.h" 37#include "BandwidthController.h" 38 39 40extern "C" int ifc_init(void); 41extern "C" int ifc_close(void); 42extern "C" int ifc_get_hwaddr(const char *name, void *ptr); 43extern "C" int ifc_get_info(const char *name, in_addr_t *addr, int *prefixLength, unsigned *flags); 44extern "C" int ifc_get_addr(const char *name, in_addr_t *addr); 45extern "C" int ifc_set_addr(const char *name, in_addr_t addr); 46extern "C" int ifc_set_prefixLength(const char *name, int prefixLength); 47extern "C" int ifc_up(const char *name); 48extern "C" int ifc_down(const char *name); 49extern "C" int ifc_add_route(const char *name, const char *dst, int prefix_length, const char *gw); 50extern "C" int ifc_remove_route(const char *name, const char *dst, int p_length, const char *gw); 51 52TetherController *CommandListener::sTetherCtrl = NULL; 53NatController *CommandListener::sNatCtrl = NULL; 54PppController *CommandListener::sPppCtrl = NULL; 55PanController *CommandListener::sPanCtrl = NULL; 56SoftapController *CommandListener::sSoftapCtrl = NULL; 57BandwidthController * CommandListener::sBandwidthCtrl = NULL; 58ResolverController *CommandListener::sResolverCtrl = NULL; 59 60CommandListener::CommandListener() : 61 FrameworkListener("netd") { 62 registerCmd(new InterfaceCmd()); 63 registerCmd(new IpFwdCmd()); 64 registerCmd(new TetherCmd()); 65 registerCmd(new NatCmd()); 66 registerCmd(new ListTtysCmd()); 67 registerCmd(new PppdCmd()); 68 registerCmd(new PanCmd()); 69 registerCmd(new SoftapCmd()); 70 registerCmd(new BandwidthControlCmd()); 71 registerCmd(new ResolverCmd()); 72 73 if (!sTetherCtrl) 74 sTetherCtrl = new TetherController(); 75 if (!sNatCtrl) 76 sNatCtrl = new NatController(); 77 if (!sPppCtrl) 78 sPppCtrl = new PppController(); 79 if (!sPanCtrl) 80 sPanCtrl = new PanController(); 81 if (!sSoftapCtrl) 82 sSoftapCtrl = new SoftapController(); 83 if (!sBandwidthCtrl) 84 sBandwidthCtrl = new BandwidthController(); 85 if (!sResolverCtrl) 86 sResolverCtrl = new ResolverController(); 87} 88 89CommandListener::InterfaceCmd::InterfaceCmd() : 90 NetdCommand("interface") { 91} 92 93int CommandListener::InterfaceCmd::runCommand(SocketClient *cli, 94 int argc, char **argv) { 95 if (argc < 2) { 96 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 97 return 0; 98 } 99 100 if (!strcmp(argv[1], "list")) { 101 DIR *d; 102 struct dirent *de; 103 104 if (!(d = opendir("/sys/class/net"))) { 105 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true); 106 return 0; 107 } 108 109 while((de = readdir(d))) { 110 if (de->d_name[0] == '.') 111 continue; 112 cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false); 113 } 114 closedir(d); 115 cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false); 116 return 0; 117 } else if (!strcmp(argv[1], "readrxcounter")) { 118 if (argc != 3) { 119 cli->sendMsg(ResponseCode::CommandSyntaxError, 120 "Usage: interface readrxcounter <interface>", false); 121 return 0; 122 } 123 unsigned long rx = 0, tx = 0; 124 if (readInterfaceCounters(argv[2], &rx, &tx)) { 125 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 126 return 0; 127 } 128 129 char *msg; 130 asprintf(&msg, "%lu", rx); 131 cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false); 132 free(msg); 133 134 return 0; 135 } else if (!strcmp(argv[1], "readtxcounter")) { 136 if (argc != 3) { 137 cli->sendMsg(ResponseCode::CommandSyntaxError, 138 "Usage: interface readtxcounter <interface>", false); 139 return 0; 140 } 141 unsigned long rx = 0, tx = 0; 142 if (readInterfaceCounters(argv[2], &rx, &tx)) { 143 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 144 return 0; 145 } 146 147 char *msg = NULL; 148 asprintf(&msg, "%lu", tx); 149 cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false); 150 free(msg); 151 return 0; 152 } else if (!strcmp(argv[1], "getthrottle")) { 153 if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) { 154 cli->sendMsg(ResponseCode::CommandSyntaxError, 155 "Usage: interface getthrottle <interface> <rx|tx>", false); 156 return 0; 157 } 158 int val = 0; 159 int rc = 0; 160 int voldRc = ResponseCode::InterfaceRxThrottleResult; 161 162 if (!strcmp(argv[3], "rx")) { 163 rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val); 164 } else { 165 rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val); 166 voldRc = ResponseCode::InterfaceTxThrottleResult; 167 } 168 if (rc) { 169 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true); 170 } else { 171 char *msg = NULL; 172 asprintf(&msg, "%u", val); 173 cli->sendMsg(voldRc, msg, false); 174 free(msg); 175 return 0; 176 } 177 return 0; 178 } else if (!strcmp(argv[1], "setthrottle")) { 179 if (argc != 5) { 180 cli->sendMsg(ResponseCode::CommandSyntaxError, 181 "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false); 182 return 0; 183 } 184 if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) { 185 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true); 186 } else { 187 cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false); 188 } 189 return 0; 190 } else { 191 /* 192 * These commands take a minimum of 3 arguments 193 */ 194 if (argc < 3) { 195 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 196 return 0; 197 } 198 199 if (!strcmp(argv[1], "route")) { 200 int prefix_length = 0; 201 if (argc < 7) { 202 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 203 return 0; 204 } 205 if (sscanf(argv[5], "%d", &prefix_length) != 1) { 206 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false); 207 return 0; 208 } 209 if (!strcmp(argv[2], "add")) { 210 if (ifc_add_route(argv[3], argv[4], prefix_length, argv[6])) { 211 cli->sendMsg(ResponseCode::OperationFailed, "Failed to add route", true); 212 } else { 213 cli->sendMsg(ResponseCode::CommandOkay, "Route added", false); 214 } 215 } else if (!strcmp(argv[2], "remove")) { 216 if (ifc_remove_route(argv[3], argv[4], prefix_length, argv[6])) { 217 cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove route", true); 218 } else { 219 cli->sendMsg(ResponseCode::CommandOkay, "Route removed", false); 220 } 221 } else { 222 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 223 } 224 return 0; 225 } 226 227 if (!strcmp(argv[1], "getcfg")) { 228 struct in_addr addr; 229 int prefixLength; 230 unsigned char hwaddr[6]; 231 unsigned flags = 0; 232 233 ifc_init(); 234 memset(hwaddr, 0, sizeof(hwaddr)); 235 236 if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) { 237 cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); 238 ifc_close(); 239 return 0; 240 } 241 242 if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) { 243 LOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno)); 244 } 245 246 char *addr_s = strdup(inet_ntoa(addr)); 247 const char *updown, *brdcst, *loopbk, *ppp, *running, *multi; 248 249 updown = (flags & IFF_UP) ? "up" : "down"; 250 brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; 251 loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; 252 ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; 253 running = (flags & IFF_RUNNING) ? " running" : ""; 254 multi = (flags & IFF_MULTICAST) ? " multicast" : ""; 255 256 char *flag_s; 257 258 asprintf(&flag_s, "[%s%s%s%s%s%s]", updown, brdcst, loopbk, ppp, running, multi); 259 260 char *msg = NULL; 261 asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s", 262 hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5], 263 addr_s, prefixLength, flag_s); 264 265 cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false); 266 267 free(addr_s); 268 free(flag_s); 269 free(msg); 270 271 ifc_close(); 272 return 0; 273 } else if (!strcmp(argv[1], "setcfg")) { 274 // arglist: iface addr prefixLength [flags] 275 if (argc < 5) { 276 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 277 return 0; 278 } 279 LOGD("Setting iface cfg"); 280 281 struct in_addr addr; 282 unsigned flags = 0; 283 284 if (!inet_aton(argv[3], &addr)) { 285 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 286 return 0; 287 } 288 289 ifc_init(); 290 if (ifc_set_addr(argv[2], addr.s_addr)) { 291 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true); 292 ifc_close(); 293 return 0; 294 } 295 296 //Set prefix length on a non zero address 297 if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) { 298 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true); 299 ifc_close(); 300 return 0; 301 } 302 303 /* Process flags */ 304 /* read from "[XX" arg to "YY]" arg */ 305 bool bStarted = false; 306 for (int i = 5; i < argc; i++) { 307 char *flag = argv[i]; 308 if (!bStarted) { 309 if (*flag == '[') { 310 flag++; 311 bStarted = true; 312 } else { 313 continue; 314 } 315 } 316 int len = strlen(flag); 317 if (flag[len-1] == ']') { 318 i = argc; // stop after this loop 319 flag[len-1] = 0; 320 } 321 if (!strcmp(flag, "up")) { 322 LOGD("Trying to bring up %s", argv[2]); 323 if (ifc_up(argv[2])) { 324 LOGE("Error upping interface"); 325 cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true); 326 ifc_close(); 327 return 0; 328 } 329 } else if (!strcmp(flag, "down")) { 330 LOGD("Trying to bring down %s", argv[2]); 331 if (ifc_down(argv[2])) { 332 LOGE("Error downing interface"); 333 cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true); 334 ifc_close(); 335 return 0; 336 } 337 } else if (!strcmp(flag, "broadcast")) { 338 LOGD("broadcast flag ignored"); 339 } else if (!strcmp(flag, "multicast")) { 340 LOGD("multicast flag ignored"); 341 } else { 342 cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false); 343 ifc_close(); 344 return 0; 345 } 346 } 347 348 cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false); 349 ifc_close(); 350 return 0; 351 } else if (!strcmp(argv[1], "clearaddrs")) { 352 // arglist: iface 353 unsigned count, addr; 354 355 //IPv4 only right now 356 LOGD("Clearing all IP addresses on %s", argv[2]); 357 358 ifc_init(); 359 for (count=0, addr=1;((addr != 0) && (count < 255)); count++) { 360 if (ifc_get_addr(argv[2], &addr) < 0) 361 break; 362 if (addr) 363 ifc_set_addr(argv[2], 0); 364 } 365 ifc_close(); 366 cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false); 367 return 0; 368 } else if (!strcmp(argv[1], "ipv6privacyextensions")) { 369 if (argc != 4) { 370 cli->sendMsg(ResponseCode::CommandSyntaxError, 371 "Usage: interface ipv6privacyextensions <interface> <enable|disable>", 372 false); 373 return 0; 374 } 375 376 char *tmp = NULL; 377 asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/use_tempaddr", argv[2]); 378 int fd = open(tmp, O_WRONLY); 379 if (fd < 0) { 380 LOGE("Failed to open %s (%s)", tmp, strerror(errno)); 381 free(tmp); 382 cli->sendMsg(ResponseCode::OperationFailed, 383 "Failed to set ipv6 privacy extensions", true); 384 return 0; 385 } 386 387 if (write(fd, (!strncmp(argv[3], "enable", 6) ? "2" : "0"), 1) != 1) { 388 LOGE("Failed to write %s (%s)", tmp, strerror(errno)); 389 close(fd); 390 free(tmp); 391 cli->sendMsg(ResponseCode::OperationFailed, 392 "Failed to set ipv6 privacy extensions", true); 393 return 0; 394 } 395 close(fd); 396 free(tmp); 397 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false); 398 return 0; 399 } else { 400 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 401 return 0; 402 } 403 } 404 return 0; 405} 406 407 408CommandListener::ListTtysCmd::ListTtysCmd() : 409 NetdCommand("list_ttys") { 410} 411 412int CommandListener::ListTtysCmd::runCommand(SocketClient *cli, 413 int argc, char **argv) { 414 TtyCollection *tlist = sPppCtrl->getTtyList(); 415 TtyCollection::iterator it; 416 417 for (it = tlist->begin(); it != tlist->end(); ++it) { 418 cli->sendMsg(ResponseCode::TtyListResult, *it, false); 419 } 420 421 cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false); 422 return 0; 423} 424 425CommandListener::IpFwdCmd::IpFwdCmd() : 426 NetdCommand("ipfwd") { 427} 428 429int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 430 int argc, char **argv) { 431 int rc = 0; 432 433 if (argc < 2) { 434 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 435 return 0; 436 } 437 438 if (!strcmp(argv[1], "status")) { 439 char *tmp = NULL; 440 441 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 442 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 443 free(tmp); 444 return 0; 445 } else if (!strcmp(argv[1], "enable")) { 446 rc = sTetherCtrl->setIpFwdEnabled(true); 447 } else if (!strcmp(argv[1], "disable")) { 448 rc = sTetherCtrl->setIpFwdEnabled(false); 449 } else { 450 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 451 return 0; 452 } 453 454 if (!rc) { 455 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 456 } else { 457 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 458 } 459 460 return 0; 461} 462 463CommandListener::TetherCmd::TetherCmd() : 464 NetdCommand("tether") { 465} 466 467int CommandListener::TetherCmd::runCommand(SocketClient *cli, 468 int argc, char **argv) { 469 int rc = 0; 470 471 if (argc < 2) { 472 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 473 return 0; 474 } 475 476 if (!strcmp(argv[1], "stop")) { 477 rc = sTetherCtrl->stopTethering(); 478 } else if (!strcmp(argv[1], "status")) { 479 char *tmp = NULL; 480 481 asprintf(&tmp, "Tethering services %s", 482 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 483 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 484 free(tmp); 485 return 0; 486 } else { 487 /* 488 * These commands take a minimum of 4 arguments 489 */ 490 if (argc < 4) { 491 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 492 return 0; 493 } 494 495 if (!strcmp(argv[1], "start")) { 496 if (argc % 2 == 1) { 497 cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false); 498 return 0; 499 } 500 501 int num_addrs = argc - 2; 502 int arg_index = 2; 503 int array_index = 0; 504 in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs); 505 while (array_index < num_addrs) { 506 if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) { 507 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 508 free(addrs); 509 return 0; 510 } 511 } 512 rc = sTetherCtrl->startTethering(num_addrs, addrs); 513 free(addrs); 514 } else if (!strcmp(argv[1], "interface")) { 515 if (!strcmp(argv[2], "add")) { 516 rc = sTetherCtrl->tetherInterface(argv[3]); 517 } else if (!strcmp(argv[2], "remove")) { 518 rc = sTetherCtrl->untetherInterface(argv[3]); 519 } else if (!strcmp(argv[2], "list")) { 520 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 521 InterfaceCollection::iterator it; 522 523 for (it = ilist->begin(); it != ilist->end(); ++it) { 524 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 525 } 526 } else { 527 cli->sendMsg(ResponseCode::CommandParameterError, 528 "Unknown tether interface operation", false); 529 return 0; 530 } 531 } else if (!strcmp(argv[1], "dns")) { 532 if (!strcmp(argv[2], "set")) { 533 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 534 } else if (!strcmp(argv[2], "list")) { 535 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 536 NetAddressCollection::iterator it; 537 538 for (it = dlist->begin(); it != dlist->end(); ++it) { 539 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 540 } 541 } else { 542 cli->sendMsg(ResponseCode::CommandParameterError, 543 "Unknown tether interface operation", false); 544 return 0; 545 } 546 } else { 547 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 548 return 0; 549 } 550 } 551 552 if (!rc) { 553 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 554 } else { 555 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 556 } 557 558 return 0; 559} 560 561CommandListener::NatCmd::NatCmd() : 562 NetdCommand("nat") { 563} 564 565int CommandListener::NatCmd::runCommand(SocketClient *cli, 566 int argc, char **argv) { 567 int rc = 0; 568 569 if (argc < 3) { 570 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 571 return 0; 572 } 573 574 if (!strcmp(argv[1], "enable")) { 575 rc = sNatCtrl->enableNat(argv[2], argv[3]); 576 } else if (!strcmp(argv[1], "disable")) { 577 rc = sNatCtrl->disableNat(argv[2], argv[3]); 578 } else { 579 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 580 return 0; 581 } 582 583 if (!rc) { 584 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 585 } else { 586 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 587 } 588 589 return 0; 590} 591 592CommandListener::PppdCmd::PppdCmd() : 593 NetdCommand("pppd") { 594} 595 596int CommandListener::PppdCmd::runCommand(SocketClient *cli, 597 int argc, char **argv) { 598 int rc = 0; 599 600 if (argc < 3) { 601 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 602 return 0; 603 } 604 605 if (!strcmp(argv[1], "attach")) { 606 struct in_addr l, r, dns1, dns2; 607 608 memset(&dns1, sizeof(struct in_addr), 0); 609 memset(&dns2, sizeof(struct in_addr), 0); 610 611 if (!inet_aton(argv[3], &l)) { 612 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false); 613 return 0; 614 } 615 if (!inet_aton(argv[4], &r)) { 616 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false); 617 return 0; 618 } 619 if ((argc > 3) && (!inet_aton(argv[5], &dns1))) { 620 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false); 621 return 0; 622 } 623 if ((argc > 4) && (!inet_aton(argv[6], &dns2))) { 624 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false); 625 return 0; 626 } 627 rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2); 628 } else if (!strcmp(argv[1], "detach")) { 629 rc = sPppCtrl->detachPppd(argv[2]); 630 } else { 631 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false); 632 return 0; 633 } 634 635 if (!rc) { 636 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false); 637 } else { 638 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true); 639 } 640 641 return 0; 642} 643 644CommandListener::PanCmd::PanCmd() : 645 NetdCommand("pan") { 646} 647 648int CommandListener::PanCmd::runCommand(SocketClient *cli, 649 int argc, char **argv) { 650 int rc = 0; 651 652 if (argc < 2) { 653 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 654 return 0; 655 } 656 657 if (!strcmp(argv[1], "start")) { 658 rc = sPanCtrl->startPan(); 659 } else if (!strcmp(argv[1], "stop")) { 660 rc = sPanCtrl->stopPan(); 661 } else if (!strcmp(argv[1], "status")) { 662 char *tmp = NULL; 663 664 asprintf(&tmp, "Pan services %s", 665 (sPanCtrl->isPanStarted() ? "started" : "stopped")); 666 cli->sendMsg(ResponseCode::PanStatusResult, tmp, false); 667 free(tmp); 668 return 0; 669 } else { 670 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pan cmd", false); 671 return 0; 672 } 673 674 if (!rc) { 675 cli->sendMsg(ResponseCode::CommandOkay, "Pan operation succeeded", false); 676 } else { 677 cli->sendMsg(ResponseCode::OperationFailed, "Pan operation failed", true); 678 } 679 680 return 0; 681} 682 683CommandListener::SoftapCmd::SoftapCmd() : 684 NetdCommand("softap") { 685} 686 687int CommandListener::SoftapCmd::runCommand(SocketClient *cli, 688 int argc, char **argv) { 689 int rc = 0, flag = 0; 690 char *retbuf = NULL; 691 692 if (argc < 2) { 693 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false); 694 return 0; 695 } 696 697 if (!strcmp(argv[1], "start")) { 698 rc = sSoftapCtrl->startDriver(argv[2]); 699 } else if (!strcmp(argv[1], "stop")) { 700 rc = sSoftapCtrl->stopDriver(argv[2]); 701 } else if (!strcmp(argv[1], "startap")) { 702 rc = sSoftapCtrl->startSoftap(); 703 } else if (!strcmp(argv[1], "stopap")) { 704 rc = sSoftapCtrl->stopSoftap(); 705 } else if (!strcmp(argv[1], "fwreload")) { 706 rc = sSoftapCtrl->fwReloadSoftap(argc, argv); 707 } else if (!strcmp(argv[1], "clients")) { 708 rc = sSoftapCtrl->clientsSoftap(&retbuf); 709 if (!rc) { 710 cli->sendMsg(ResponseCode::CommandOkay, retbuf, false); 711 free(retbuf); 712 return 0; 713 } 714 } else if (!strcmp(argv[1], "status")) { 715 asprintf(&retbuf, "Softap service %s", 716 (sSoftapCtrl->isSoftapStarted() ? "started" : "stopped")); 717 cli->sendMsg(ResponseCode::SoftapStatusResult, retbuf, false); 718 free(retbuf); 719 return 0; 720 } else if (!strcmp(argv[1], "set")) { 721 rc = sSoftapCtrl->setSoftap(argc, argv); 722 } else { 723 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Unknown cmd", false); 724 return 0; 725 } 726 727 if (!rc) { 728 cli->sendMsg(ResponseCode::CommandOkay, "Softap operation succeeded", false); 729 } else { 730 cli->sendMsg(ResponseCode::OperationFailed, "Softap operation failed", true); 731 } 732 733 return 0; 734} 735 736CommandListener::ResolverCmd::ResolverCmd() : 737 NetdCommand("resolver") { 738} 739 740int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) { 741 int rc = 0; 742 struct in_addr addr; 743 744 if (argc < 2) { 745 cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false); 746 return 0; 747 } 748 749 if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>" 750 if (argc == 3) { 751 rc = sResolverCtrl->setDefaultInterface(argv[2]); 752 } else { 753 cli->sendMsg(ResponseCode::CommandSyntaxError, 754 "Wrong number of arguments to resolver setdefaultif", false); 755 return 0; 756 } 757 } else if (!strcmp(argv[1], "setifdns")) { // "resolver setifdns <iface> <dns1> <dns2> ..." 758 if (argc >= 4) { 759 rc = sResolverCtrl->setInterfaceDnsServers(argv[2], &argv[3], argc - 3); 760 } else { 761 cli->sendMsg(ResponseCode::CommandSyntaxError, 762 "Wrong number of arguments to resolver setifdns", false); 763 return 0; 764 } 765 766 // set the address of the interface to which the name servers 767 // are bound. Required in order to bind to right interface when 768 // doing the dns query. 769 if (!rc) { 770 ifc_init(); 771 ifc_get_info(argv[2], &addr.s_addr, NULL, 0); 772 773 rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr); 774 } 775 } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif" 776 if (argc == 2) { 777 rc = sResolverCtrl->flushDefaultDnsCache(); 778 } else { 779 cli->sendMsg(ResponseCode::CommandSyntaxError, 780 "Wrong number of arguments to resolver flushdefaultif", false); 781 return 0; 782 } 783 } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>" 784 if (argc == 3) { 785 rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]); 786 } else { 787 cli->sendMsg(ResponseCode::CommandSyntaxError, 788 "Wrong number of arguments to resolver setdefaultif", false); 789 return 0; 790 } 791 } else { 792 cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false); 793 return 0; 794 } 795 796 if (!rc) { 797 cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false); 798 } else { 799 cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true); 800 } 801 802 return 0; 803} 804 805int CommandListener::readInterfaceCounters(const char *iface, unsigned long *rx, unsigned long *tx) { 806 FILE *fp = fopen("/proc/net/dev", "r"); 807 if (!fp) { 808 LOGE("Failed to open /proc/net/dev (%s)", strerror(errno)); 809 return -1; 810 } 811 812 char buffer[512]; 813 814 fgets(buffer, sizeof(buffer), fp); // Header 1 815 fgets(buffer, sizeof(buffer), fp); // Header 2 816 while(fgets(buffer, sizeof(buffer), fp)) { 817 buffer[strlen(buffer)-1] = '\0'; 818 819 char name[31]; 820 unsigned long d; 821 sscanf(buffer, "%30s %lu %lu %lu %lu %lu %lu %lu %lu %lu", 822 name, rx, &d, &d, &d, &d, &d, &d, &d, tx); 823 char *rxString = strchr(name, ':'); 824 *rxString = '\0'; 825 rxString++; 826 // when the rx count gets too big it changes from "name: 999" to "name:1000" 827 // and the sscanf munge the two together. Detect that and fix 828 // note that all the %lu will be off by one and the real tx value will be in d 829 if (*rxString != '\0') { 830 *tx = d; 831 sscanf(rxString, "%20lu", rx); 832 } 833 if (strcmp(name, iface)) { 834 continue; 835 } 836 fclose(fp); 837 return 0; 838 } 839 840 fclose(fp); 841 *rx = 0; 842 *tx = 0; 843 return 0; 844} 845 846CommandListener::BandwidthControlCmd::BandwidthControlCmd() : 847 NetdCommand("bandwidth") { 848} 849 850int CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) { 851 int rc = 0; 852 LOGD("bwctrlcmd: argc=%d argv[0]=%s", argc, argv[0]); 853 if (argc < 2) { 854 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 855 return 0; 856 } 857 858 if (!strcmp(argv[1], "enable")) { 859 rc = sBandwidthCtrl->enableBandwidthControl(); 860 } else if (!strcmp(argv[1], "disable")) { 861 rc = sBandwidthCtrl->disableBandwidthControl(); 862 863 } else if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) { 864 if (argc != 3) { 865 cli->sendMsg(ResponseCode::CommandSyntaxError, 866 "Usage: bandwidth removequota <interface>", false); 867 return 0; 868 } 869 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]); 870 871 } else if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) { 872 int64_t bytes; 873 if (argc != 2) { 874 cli->sendMsg(ResponseCode::CommandSyntaxError, 875 "Usage: bandwidth getquota", false); 876 return 0; 877 } 878 rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes); 879 if (rc) { 880 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get quota", true); 881 return 0; 882 } 883 char *msg; 884 asprintf(&msg, "%lld", bytes); 885 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 886 free(msg); 887 888 } else if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) { 889 int64_t bytes; 890 if (argc != 3) { 891 cli->sendMsg(ResponseCode::CommandSyntaxError, 892 "Usage: bandwidth getiquota <iface>", false); 893 return 0; 894 } 895 rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes); 896 if (rc) { 897 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get quota", true); 898 return 0; 899 } 900 char *msg; 901 asprintf(&msg, "%lld", bytes); 902 cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false); 903 free(msg); 904 905 } else if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) { 906 if (argc != 4) { 907 cli->sendMsg(ResponseCode::CommandSyntaxError, 908 "Usage: bandwidth setquota <interface> <bytes>", false); 909 return 0; 910 } 911 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3])); 912 913 } else if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) { 914 if (argc < 4) { 915 cli->sendMsg(ResponseCode::CommandSyntaxError, 916 "Usage: bandwidth setquotas <bytes> <interface> ...", false); 917 return 0; 918 } 919 for (int q = 3; argc >= 4; q++, argc--) { 920 rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2])); 921 if (rc) { 922 char *msg; 923 asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]); 924 cli->sendMsg(ResponseCode::OperationFailed, 925 msg, false); 926 free(msg); 927 break; 928 } 929 } 930 931 } else if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) { 932 if (argc < 3) { 933 cli->sendMsg(ResponseCode::CommandSyntaxError, 934 "Usage: bandwidth removequotas <interface> ...", false); 935 return 0; 936 } 937 for (int q = 2; argc >= 3; q++, argc--) { 938 rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]); 939 if (rc) { 940 char *msg; 941 asprintf(&msg, "bandwidth removequotas %s failed", argv[q]); 942 cli->sendMsg(ResponseCode::OperationFailed, 943 msg, false); 944 free(msg); 945 break; 946 } 947 } 948 949 } else if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) { 950 if (argc != 3) { 951 cli->sendMsg(ResponseCode::CommandSyntaxError, 952 "Usage: bandwidth removeiquota <interface>", false); 953 return 0; 954 } 955 rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]); 956 957 } else if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) { 958 if (argc != 4) { 959 cli->sendMsg(ResponseCode::CommandSyntaxError, 960 "Usage: bandwidth setiquota <interface> <bytes>", false); 961 return 0; 962 } 963 rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3])); 964 965 } else if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) { 966 if (argc < 3) { 967 cli->sendMsg(ResponseCode::CommandSyntaxError, 968 "Usage: bandwidth addnaughtyapps <appUid> ...", false); 969 return 0; 970 } 971 rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2); 972 973 } else if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) { 974 if (argc < 3) { 975 cli->sendMsg(ResponseCode::CommandSyntaxError, 976 "Usage: bandwidth removenaughtyapps <appUid> ...", false); 977 return 0; 978 } 979 rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2); 980 981 } else if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) { 982 if (argc != 3) { 983 cli->sendMsg(ResponseCode::CommandSyntaxError, 984 "Usage: bandwidth setglobalalert <bytes>", false); 985 return 0; 986 } 987 rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2])); 988 989 } else if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) { 990 if (argc != 2) { 991 cli->sendMsg(ResponseCode::CommandSyntaxError, 992 "Usage: bandwidth removeglobalalert", false); 993 return 0; 994 } 995 rc = sBandwidthCtrl->removeGlobalAlert(); 996 997 } else if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) { 998 if (argc != 3) { 999 cli->sendMsg(ResponseCode::CommandSyntaxError, 1000 "Usage: bandwidth setsharedalert <bytes>", false); 1001 return 0; 1002 } 1003 rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2])); 1004 1005 } else if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) { 1006 if (argc != 2) { 1007 cli->sendMsg(ResponseCode::CommandSyntaxError, 1008 "Usage: bandwidth removesharedalert", false); 1009 return 0; 1010 } 1011 rc = sBandwidthCtrl->removeSharedAlert(); 1012 1013 } else if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) { 1014 if (argc != 4) { 1015 cli->sendMsg(ResponseCode::CommandSyntaxError, 1016 "Usage: bandwidth setinterfacealert <interface> <bytes>", false); 1017 return 0; 1018 } 1019 rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3])); 1020 1021 } else if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) { 1022 if (argc != 3) { 1023 cli->sendMsg(ResponseCode::CommandSyntaxError, 1024 "Usage: bandwidth removeinterfacealert <interface>", false); 1025 return 0; 1026 } 1027 rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]); 1028 1029 } else { 1030 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false); 1031 return 0; 1032 } 1033 1034 if (!rc) { 1035 cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false); 1036 } else { 1037 cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", true); 1038 } 1039 return 0; 1040} 1041