CommandListener.cpp revision 80adaddfe0a997d7c9f45fafbd6f8b05e14d119c
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 26#include <linux/if.h> 27 28#define LOG_TAG "CommandListener" 29#include <cutils/log.h> 30 31#include <sysutils/SocketClient.h> 32 33#include "CommandListener.h" 34#include "ResponseCode.h" 35#include "ThrottleController.h" 36 37 38extern "C" int ifc_init(void); 39extern "C" int ifc_get_hwaddr(const char *name, void *ptr); 40extern "C" int ifc_get_info(const char *name, in_addr_t *addr, int *prefixLength, unsigned *flags); 41extern "C" int ifc_set_addr(const char *name, in_addr_t addr); 42extern "C" int ifc_set_prefixLength(const char *name, int prefixLength); 43extern "C" int ifc_up(const char *name); 44extern "C" int ifc_down(const char *name); 45extern "C" int ifc_add_route(const char *name, const char *dst, int prefix_length, const char *gw); 46extern "C" int ifc_remove_route(const char *name, const char *dst, int p_length, const char *gw); 47 48TetherController *CommandListener::sTetherCtrl = NULL; 49NatController *CommandListener::sNatCtrl = NULL; 50PppController *CommandListener::sPppCtrl = NULL; 51PanController *CommandListener::sPanCtrl = NULL; 52SoftapController *CommandListener::sSoftapCtrl = NULL; 53UsbController *CommandListener::sUsbCtrl = NULL; 54ResolverController *CommandListener::sResolverCtrl = NULL; 55 56CommandListener::CommandListener() : 57 FrameworkListener("netd") { 58 registerCmd(new InterfaceCmd()); 59 registerCmd(new IpFwdCmd()); 60 registerCmd(new TetherCmd()); 61 registerCmd(new NatCmd()); 62 registerCmd(new ListTtysCmd()); 63 registerCmd(new PppdCmd()); 64 registerCmd(new PanCmd()); 65 registerCmd(new SoftapCmd()); 66 registerCmd(new UsbCmd()); 67 registerCmd(new ResolverCmd()); 68 69 if (!sTetherCtrl) 70 sTetherCtrl = new TetherController(); 71 if (!sNatCtrl) 72 sNatCtrl = new NatController(); 73 if (!sPppCtrl) 74 sPppCtrl = new PppController(); 75 if (!sPanCtrl) 76 sPanCtrl = new PanController(); 77 if (!sSoftapCtrl) 78 sSoftapCtrl = new SoftapController(); 79 if (!sUsbCtrl) 80 sUsbCtrl = new UsbController(); 81 if (!sResolverCtrl) 82 sResolverCtrl = new ResolverController(); 83} 84 85CommandListener::InterfaceCmd::InterfaceCmd() : 86 NetdCommand("interface") { 87} 88 89int CommandListener::InterfaceCmd::runCommand(SocketClient *cli, 90 int argc, char **argv) { 91 if (argc < 2) { 92 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 93 return 0; 94 } 95 96 if (!strcmp(argv[1], "list")) { 97 DIR *d; 98 struct dirent *de; 99 100 if (!(d = opendir("/sys/class/net"))) { 101 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true); 102 return 0; 103 } 104 105 while((de = readdir(d))) { 106 if (de->d_name[0] == '.') 107 continue; 108 cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false); 109 } 110 closedir(d); 111 cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false); 112 return 0; 113 } else if (!strcmp(argv[1], "readrxcounter")) { 114 if (argc != 3) { 115 cli->sendMsg(ResponseCode::CommandSyntaxError, 116 "Usage: interface readrxcounter <interface>", false); 117 return 0; 118 } 119 unsigned long rx = 0, tx = 0; 120 if (readInterfaceCounters(argv[2], &rx, &tx)) { 121 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 122 return 0; 123 } 124 125 char *msg; 126 asprintf(&msg, "%lu", rx); 127 cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false); 128 free(msg); 129 130 return 0; 131 } else if (!strcmp(argv[1], "readtxcounter")) { 132 if (argc != 3) { 133 cli->sendMsg(ResponseCode::CommandSyntaxError, 134 "Usage: interface readtxcounter <interface>", false); 135 return 0; 136 } 137 unsigned long rx = 0, tx = 0; 138 if (readInterfaceCounters(argv[2], &rx, &tx)) { 139 cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); 140 return 0; 141 } 142 143 char *msg = NULL; 144 asprintf(&msg, "%lu", tx); 145 cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false); 146 free(msg); 147 return 0; 148 } else if (!strcmp(argv[1], "getthrottle")) { 149 if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) { 150 cli->sendMsg(ResponseCode::CommandSyntaxError, 151 "Usage: interface getthrottle <interface> <rx|tx>", false); 152 return 0; 153 } 154 int val = 0; 155 int rc = 0; 156 int voldRc = ResponseCode::InterfaceRxThrottleResult; 157 158 if (!strcmp(argv[3], "rx")) { 159 rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val); 160 } else { 161 rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val); 162 voldRc = ResponseCode::InterfaceTxThrottleResult; 163 } 164 if (rc) { 165 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true); 166 } else { 167 char *msg = NULL; 168 asprintf(&msg, "%u", val); 169 cli->sendMsg(voldRc, msg, false); 170 free(msg); 171 return 0; 172 } 173 return 0; 174 } else if (!strcmp(argv[1], "setthrottle")) { 175 if (argc != 5) { 176 cli->sendMsg(ResponseCode::CommandSyntaxError, 177 "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false); 178 return 0; 179 } 180 if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) { 181 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true); 182 } else { 183 cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false); 184 } 185 return 0; 186 } else { 187 /* 188 * These commands take a minimum of 3 arguments 189 */ 190 if (argc < 3) { 191 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 192 return 0; 193 } 194 195 if (!strcmp(argv[1], "route")) { 196 int prefix_length = 0; 197 if (argc < 7) { 198 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 199 return 0; 200 } 201 if (sscanf(argv[5], "%d", &prefix_length) != 1) { 202 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false); 203 return 0; 204 } 205 if (!strcmp(argv[2], "add")) { 206 if (ifc_add_route(argv[3], argv[4], prefix_length, argv[6])) { 207 cli->sendMsg(ResponseCode::OperationFailed, "Failed to add route", true); 208 } else { 209 cli->sendMsg(ResponseCode::CommandOkay, "Route added", false); 210 } 211 } else if (!strcmp(argv[2], "remove")) { 212 if (ifc_remove_route(argv[3], argv[4], prefix_length, argv[6])) { 213 cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove route", true); 214 } else { 215 cli->sendMsg(ResponseCode::CommandOkay, "Route removed", false); 216 } 217 } else { 218 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 219 } 220 return 0; 221 } 222 223 if (!strcmp(argv[1], "getcfg")) { 224 struct in_addr addr; 225 int prefixLength; 226 unsigned char hwaddr[6]; 227 unsigned flags = 0; 228 229 ifc_init(); 230 memset(hwaddr, 0, sizeof(hwaddr)); 231 232 if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) { 233 cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); 234 return 0; 235 } 236 237 if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) { 238 LOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno)); 239 } 240 241 char *addr_s = strdup(inet_ntoa(addr)); 242 const char *updown, *brdcst, *loopbk, *ppp, *running, *multi; 243 244 updown = (flags & IFF_UP) ? "up" : "down"; 245 brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; 246 loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; 247 ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; 248 running = (flags & IFF_RUNNING) ? " running" : ""; 249 multi = (flags & IFF_MULTICAST) ? " multicast" : ""; 250 251 char *flag_s; 252 253 asprintf(&flag_s, "[%s%s%s%s%s%s]", updown, brdcst, loopbk, ppp, running, multi); 254 255 char *msg = NULL; 256 asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s", 257 hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5], 258 addr_s, prefixLength, flag_s); 259 260 cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false); 261 262 free(addr_s); 263 free(flag_s); 264 free(msg); 265 return 0; 266 } else if (!strcmp(argv[1], "setcfg")) { 267 // arglist: iface addr prefixLength [flags] 268 if (argc < 5) { 269 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 270 return 0; 271 } 272 LOGD("Setting iface cfg"); 273 274 struct in_addr addr; 275 unsigned flags = 0; 276 277 if (!inet_aton(argv[3], &addr)) { 278 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 279 return 0; 280 } 281 282 ifc_init(); 283 if (ifc_set_addr(argv[2], addr.s_addr)) { 284 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true); 285 return 0; 286 } 287 288 if (ifc_set_prefixLength(argv[2], atoi(argv[4]))) { 289 cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true); 290 return 0; 291 } 292 293 /* Process flags */ 294 /* read from "[XX" arg to "YY]" arg */ 295 bool bStarted = false; 296 for (int i = 5; i < argc; i++) { 297 char *flag = argv[i]; 298 if (!bStarted) { 299 if (*flag == '[') { 300 flag++; 301 bStarted = true; 302 } else { 303 continue; 304 } 305 } 306 int len = strlen(flag); 307 if (flag[len-1] == ']') { 308 i = argc; // stop after this loop 309 flag[len-1] = 0; 310 } 311 if (!strcmp(flag, "up")) { 312 LOGD("Trying to bring up %s", argv[2]); 313 if (ifc_up(argv[2])) { 314 LOGE("Error upping interface"); 315 cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true); 316 return 0; 317 } 318 } else if (!strcmp(flag, "down")) { 319 LOGD("Trying to bring down %s", argv[2]); 320 if (ifc_down(argv[2])) { 321 LOGE("Error downing interface"); 322 cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true); 323 return 0; 324 } 325 } else if (!strcmp(flag, "broadcast")) { 326 LOGD("broadcast flag ignored"); 327 } else if (!strcmp(flag, "multicast")) { 328 LOGD("multicast flag ignored"); 329 } else { 330 cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false); 331 return 0; 332 } 333 } 334 cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false); 335 return 0; 336 } else { 337 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); 338 return 0; 339 } 340 } 341 return 0; 342} 343 344CommandListener::ListTtysCmd::ListTtysCmd() : 345 NetdCommand("list_ttys") { 346} 347 348int CommandListener::ListTtysCmd::runCommand(SocketClient *cli, 349 int argc, char **argv) { 350 TtyCollection *tlist = sPppCtrl->getTtyList(); 351 TtyCollection::iterator it; 352 353 for (it = tlist->begin(); it != tlist->end(); ++it) { 354 cli->sendMsg(ResponseCode::TtyListResult, *it, false); 355 } 356 357 cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false); 358 return 0; 359} 360 361CommandListener::IpFwdCmd::IpFwdCmd() : 362 NetdCommand("ipfwd") { 363} 364 365int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, 366 int argc, char **argv) { 367 int rc = 0; 368 369 if (argc < 2) { 370 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 371 return 0; 372 } 373 374 if (!strcmp(argv[1], "status")) { 375 char *tmp = NULL; 376 377 asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled")); 378 cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false); 379 free(tmp); 380 return 0; 381 } else if (!strcmp(argv[1], "enable")) { 382 rc = sTetherCtrl->setIpFwdEnabled(true); 383 } else if (!strcmp(argv[1], "disable")) { 384 rc = sTetherCtrl->setIpFwdEnabled(false); 385 } else { 386 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false); 387 return 0; 388 } 389 390 if (!rc) { 391 cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false); 392 } else { 393 cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true); 394 } 395 396 return 0; 397} 398 399CommandListener::TetherCmd::TetherCmd() : 400 NetdCommand("tether") { 401} 402 403int CommandListener::TetherCmd::runCommand(SocketClient *cli, 404 int argc, char **argv) { 405 int rc = 0; 406 407 if (argc < 2) { 408 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 409 return 0; 410 } 411 412 if (!strcmp(argv[1], "stop")) { 413 rc = sTetherCtrl->stopTethering(); 414 } else if (!strcmp(argv[1], "status")) { 415 char *tmp = NULL; 416 417 asprintf(&tmp, "Tethering services %s", 418 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped")); 419 cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false); 420 free(tmp); 421 return 0; 422 } else { 423 /* 424 * These commands take a minimum of 4 arguments 425 */ 426 if (argc < 4) { 427 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 428 return 0; 429 } 430 431 if (!strcmp(argv[1], "start")) { 432 if (argc % 2 == 1) { 433 cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false); 434 return 0; 435 } 436 437 int num_addrs = argc - 2; 438 int arg_index = 2; 439 int array_index = 0; 440 in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs); 441 while (array_index < num_addrs) { 442 if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) { 443 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); 444 free(addrs); 445 return 0; 446 } 447 } 448 rc = sTetherCtrl->startTethering(num_addrs, addrs); 449 free(addrs); 450 } else if (!strcmp(argv[1], "interface")) { 451 if (!strcmp(argv[2], "add")) { 452 rc = sTetherCtrl->tetherInterface(argv[3]); 453 } else if (!strcmp(argv[2], "remove")) { 454 rc = sTetherCtrl->untetherInterface(argv[3]); 455 } else if (!strcmp(argv[2], "list")) { 456 InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList(); 457 InterfaceCollection::iterator it; 458 459 for (it = ilist->begin(); it != ilist->end(); ++it) { 460 cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false); 461 } 462 } else { 463 cli->sendMsg(ResponseCode::CommandParameterError, 464 "Unknown tether interface operation", false); 465 return 0; 466 } 467 } else if (!strcmp(argv[1], "dns")) { 468 if (!strcmp(argv[2], "set")) { 469 rc = sTetherCtrl->setDnsForwarders(&argv[3], argc - 3); 470 } else if (!strcmp(argv[2], "list")) { 471 NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders(); 472 NetAddressCollection::iterator it; 473 474 for (it = dlist->begin(); it != dlist->end(); ++it) { 475 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false); 476 } 477 } else { 478 cli->sendMsg(ResponseCode::CommandParameterError, 479 "Unknown tether interface operation", false); 480 return 0; 481 } 482 } else { 483 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false); 484 return 0; 485 } 486 } 487 488 if (!rc) { 489 cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false); 490 } else { 491 cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true); 492 } 493 494 return 0; 495} 496 497CommandListener::NatCmd::NatCmd() : 498 NetdCommand("nat") { 499} 500 501int CommandListener::NatCmd::runCommand(SocketClient *cli, 502 int argc, char **argv) { 503 int rc = 0; 504 505 if (argc < 3) { 506 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 507 return 0; 508 } 509 510 if (!strcmp(argv[1], "enable")) { 511 rc = sNatCtrl->enableNat(argv[2], argv[3]); 512 } else if (!strcmp(argv[1], "disable")) { 513 rc = sNatCtrl->disableNat(argv[2], argv[3]); 514 } else { 515 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false); 516 return 0; 517 } 518 519 if (!rc) { 520 cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false); 521 } else { 522 cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true); 523 } 524 525 return 0; 526} 527 528CommandListener::PppdCmd::PppdCmd() : 529 NetdCommand("pppd") { 530} 531 532int CommandListener::PppdCmd::runCommand(SocketClient *cli, 533 int argc, char **argv) { 534 int rc = 0; 535 536 if (argc < 3) { 537 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 538 return 0; 539 } 540 541 if (!strcmp(argv[1], "attach")) { 542 struct in_addr l, r, dns1, dns2; 543 544 memset(&dns1, sizeof(struct in_addr), 0); 545 memset(&dns2, sizeof(struct in_addr), 0); 546 547 if (!inet_aton(argv[3], &l)) { 548 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false); 549 return 0; 550 } 551 if (!inet_aton(argv[4], &r)) { 552 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false); 553 return 0; 554 } 555 if ((argc > 3) && (!inet_aton(argv[5], &dns1))) { 556 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false); 557 return 0; 558 } 559 if ((argc > 4) && (!inet_aton(argv[6], &dns2))) { 560 cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false); 561 return 0; 562 } 563 rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2); 564 } else if (!strcmp(argv[1], "detach")) { 565 rc = sPppCtrl->detachPppd(argv[2]); 566 } else { 567 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false); 568 return 0; 569 } 570 571 if (!rc) { 572 cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false); 573 } else { 574 cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true); 575 } 576 577 return 0; 578} 579 580CommandListener::PanCmd::PanCmd() : 581 NetdCommand("pan") { 582} 583 584int CommandListener::PanCmd::runCommand(SocketClient *cli, 585 int argc, char **argv) { 586 int rc = 0; 587 588 if (argc < 2) { 589 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); 590 return 0; 591 } 592 593 if (!strcmp(argv[1], "start")) { 594 rc = sPanCtrl->startPan(); 595 } else if (!strcmp(argv[1], "stop")) { 596 rc = sPanCtrl->stopPan(); 597 } else if (!strcmp(argv[1], "status")) { 598 char *tmp = NULL; 599 600 asprintf(&tmp, "Pan services %s", 601 (sPanCtrl->isPanStarted() ? "started" : "stopped")); 602 cli->sendMsg(ResponseCode::PanStatusResult, tmp, false); 603 free(tmp); 604 return 0; 605 } else { 606 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pan cmd", false); 607 return 0; 608 } 609 610 if (!rc) { 611 cli->sendMsg(ResponseCode::CommandOkay, "Pan operation succeeded", false); 612 } else { 613 cli->sendMsg(ResponseCode::OperationFailed, "Pan operation failed", true); 614 } 615 616 return 0; 617} 618 619CommandListener::SoftapCmd::SoftapCmd() : 620 NetdCommand("softap") { 621} 622 623int CommandListener::SoftapCmd::runCommand(SocketClient *cli, 624 int argc, char **argv) { 625 int rc = 0, flag = 0; 626 627 if (argc < 2) { 628 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false); 629 return 0; 630 } 631 632 if (!strcmp(argv[1], "start")) { 633 rc = sSoftapCtrl->startDriver(argv[2]); 634 } else if (!strcmp(argv[1], "stop")) { 635 rc = sSoftapCtrl->stopDriver(argv[2]); 636 } else if (!strcmp(argv[1], "startap")) { 637 rc = sSoftapCtrl->startSoftap(); 638 } else if (!strcmp(argv[1], "stopap")) { 639 rc = sSoftapCtrl->stopSoftap(); 640 } else if (!strcmp(argv[1], "fwreload")) { 641 rc = sSoftapCtrl->fwReloadSoftap(argc, argv); 642 } else if (!strcmp(argv[1], "status")) { 643 char *tmp = NULL; 644 645 asprintf(&tmp, "Softap service %s", 646 (sSoftapCtrl->isSoftapStarted() ? "started" : "stopped")); 647 cli->sendMsg(ResponseCode::SoftapStatusResult, tmp, false); 648 free(tmp); 649 return 0; 650 } else if (!strcmp(argv[1], "set")) { 651 rc = sSoftapCtrl->setSoftap(argc, argv); 652 } else { 653 cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Unknown cmd", false); 654 return 0; 655 } 656 657 if (!rc) { 658 cli->sendMsg(ResponseCode::CommandOkay, "Softap operation succeeded", false); 659 } else { 660 cli->sendMsg(ResponseCode::OperationFailed, "Softap operation failed", true); 661 } 662 663 return 0; 664} 665 666CommandListener::UsbCmd::UsbCmd() : 667 NetdCommand("usb") { 668} 669 670int CommandListener::UsbCmd::runCommand(SocketClient *cli, int argc, char **argv) { 671 int rc = 0; 672 673 if (argc < 2) { 674 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usb Missing argument", false); 675 return 0; 676 } 677 678 if (!strcmp(argv[1], "startrndis")) { 679 rc = sUsbCtrl->startRNDIS(); 680 } else if (!strcmp(argv[1], "stoprndis")) { 681 rc = sUsbCtrl->stopRNDIS(); 682 } else if (!strcmp(argv[1], "rndisstatus")) { 683 char *tmp = NULL; 684 685 asprintf(&tmp, "Usb RNDIS %s", 686 (sUsbCtrl->isRNDISStarted() ? "started" : "stopped")); 687 cli->sendMsg(ResponseCode::UsbRNDISStatusResult, tmp, false); 688 free(tmp); 689 return 0; 690 } else { 691 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usb Unknown cmd", false); 692 return 0; 693 } 694 695 if (!rc) { 696 cli->sendMsg(ResponseCode::CommandOkay, "Usb operation succeeded", false); 697 } else { 698 cli->sendMsg(ResponseCode::OperationFailed, "Softap operation failed", true); 699 } 700 701 return 0; 702} 703 704CommandListener::ResolverCmd::ResolverCmd() : 705 NetdCommand("resolver") { 706} 707 708int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **argv) { 709 int rc = 0; 710 struct in_addr addr; 711 712 if (argc < 2) { 713 cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false); 714 return 0; 715 } 716 717 if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>" 718 if (argc == 3) { 719 rc = sResolverCtrl->setDefaultInterface(argv[2]); 720 } else { 721 cli->sendMsg(ResponseCode::CommandSyntaxError, 722 "Wrong number of arguments to resolver setdefaultif", false); 723 return 0; 724 } 725 } else if (!strcmp(argv[1], "setifdns")) { // "resolver setifdns <iface> <dns1> <dns2> ..." 726 if (argc >= 4) { 727 rc = sResolverCtrl->setInterfaceDnsServers(argv[2], &argv[3], argc - 3); 728 } else { 729 cli->sendMsg(ResponseCode::CommandSyntaxError, 730 "Wrong number of arguments to resolver setifdns", false); 731 return 0; 732 } 733 734 // set the address of the interface to which the name servers 735 // are bound. Required in order to bind to right interface when 736 // doing the dns query. 737 if (!rc) { 738 ifc_init(); 739 ifc_get_info(argv[2], &addr.s_addr, NULL, 0); 740 741 rc = sResolverCtrl->setInterfaceAddress(argv[2], &addr); 742 } 743 } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif" 744 if (argc == 2) { 745 rc = sResolverCtrl->flushDefaultDnsCache(); 746 } else { 747 cli->sendMsg(ResponseCode::CommandSyntaxError, 748 "Wrong number of arguments to resolver flushdefaultif", false); 749 return 0; 750 } 751 } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>" 752 if (argc == 3) { 753 rc = sResolverCtrl->flushInterfaceDnsCache(argv[2]); 754 } else { 755 cli->sendMsg(ResponseCode::CommandSyntaxError, 756 "Wrong number of arguments to resolver setdefaultif", false); 757 return 0; 758 } 759 } else { 760 cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false); 761 return 0; 762 } 763 764 if (!rc) { 765 cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false); 766 } else { 767 cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true); 768 } 769 770 return 0; 771} 772 773int CommandListener::readInterfaceCounters(const char *iface, unsigned long *rx, unsigned long *tx) { 774 FILE *fp = fopen("/proc/net/dev", "r"); 775 if (!fp) { 776 LOGE("Failed to open /proc/net/dev (%s)", strerror(errno)); 777 return -1; 778 } 779 780 char buffer[512]; 781 782 fgets(buffer, sizeof(buffer), fp); // Header 1 783 fgets(buffer, sizeof(buffer), fp); // Header 2 784 while(fgets(buffer, sizeof(buffer), fp)) { 785 buffer[strlen(buffer)-1] = '\0'; 786 787 char name[31]; 788 unsigned long d; 789 sscanf(buffer, "%30s %lu %lu %lu %lu %lu %lu %lu %lu %lu", 790 name, rx, &d, &d, &d, &d, &d, &d, &d, tx); 791 char *rxString = strchr(name, ':'); 792 *rxString = '\0'; 793 rxString++; 794 // when the rx count gets too big it changes from "name: 999" to "name:1000" 795 // and the sscanf munge the two together. Detect that and fix 796 // note that all the %lu will be off by one and the real tx value will be in d 797 if (*rxString != '\0') { 798 *tx = d; 799 sscanf(rxString, "%20lu", rx); 800 } 801 if (strcmp(name, iface)) { 802 continue; 803 } 804 fclose(fp); 805 return 0; 806 } 807 808 fclose(fp); 809 *rx = 0; 810 *tx = 0; 811 return 0; 812} 813