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