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 <errno.h> 18 #include <fcntl.h> 19 #include <inttypes.h> 20 #include <netdb.h> 21 #include <string.h> 22 23 #include <sys/socket.h> 24 #include <sys/stat.h> 25 #include <sys/types.h> 26 #include <sys/wait.h> 27 28 #include <netinet/in.h> 29 #include <arpa/inet.h> 30 31 #include <array> 32 #include <cstdlib> 33 #include <string> 34 #include <vector> 35 36 #define LOG_TAG "TetherController" 37 #include <android-base/strings.h> 38 #include <android-base/stringprintf.h> 39 #include <cutils/log.h> 40 #include <cutils/properties.h> 41 #include <netdutils/StatusOr.h> 42 43 #include "Fwmark.h" 44 #include "NetdConstants.h" 45 #include "Permission.h" 46 #include "InterfaceController.h" 47 #include "NetworkController.h" 48 #include "ResponseCode.h" 49 #include "TetherController.h" 50 51 using android::base::Join; 52 using android::base::StringPrintf; 53 using android::base::StringAppendF; 54 using android::netdutils::StatusOr; 55 using android::netdutils::statusFromErrno; 56 57 namespace { 58 59 const char BP_TOOLS_MODE[] = "bp-tools"; 60 const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward"; 61 const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding"; 62 const char SEPARATOR[] = "|"; 63 constexpr const char kTcpBeLiberal[] = "/proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal"; 64 65 // Chosen to match AID_DNS_TETHER, as made "friendly" by fs_config_generator.py. 66 constexpr const char kDnsmasqUsername[] = "dns_tether"; 67 68 bool writeToFile(const char* filename, const char* value) { 69 int fd = open(filename, O_WRONLY | O_CLOEXEC); 70 if (fd < 0) { 71 ALOGE("Failed to open %s: %s", filename, strerror(errno)); 72 return false; 73 } 74 75 const ssize_t len = strlen(value); 76 if (write(fd, value, len) != len) { 77 ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno)); 78 close(fd); 79 return false; 80 } 81 close(fd); 82 return true; 83 } 84 85 // TODO: Consider altering TCP and UDP timeouts as well. 86 void configureForTethering(bool enabled) { 87 writeToFile(kTcpBeLiberal, enabled ? "1" : "0"); 88 } 89 90 bool configureForIPv6Router(const char *interface) { 91 return (InterfaceController::setEnableIPv6(interface, 0) == 0) 92 && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0) 93 && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0) 94 && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0) 95 && (InterfaceController::setEnableIPv6(interface, 1) == 0); 96 } 97 98 void configureForIPv6Client(const char *interface) { 99 InterfaceController::setAcceptIPv6Ra(interface, 1); 100 InterfaceController::setAcceptIPv6Dad(interface, 1); 101 InterfaceController::setIPv6DadTransmits(interface, "1"); 102 InterfaceController::setEnableIPv6(interface, 0); 103 } 104 105 bool inBpToolsMode() { 106 // In BP tools mode, do not disable IP forwarding 107 char bootmode[PROPERTY_VALUE_MAX] = {0}; 108 property_get("ro.bootmode", bootmode, "unknown"); 109 return !strcmp(BP_TOOLS_MODE, bootmode); 110 } 111 112 } // namespace 113 114 namespace android { 115 namespace net { 116 117 auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput; 118 119 const int MAX_IPT_OUTPUT_LINE_LEN = 256; 120 121 const std::string GET_TETHER_STATS_COMMAND = StringPrintf( 122 "*filter\n" 123 "-nvx -L %s\n" 124 "COMMIT\n", android::net::TetherController::LOCAL_TETHER_COUNTERS_CHAIN); 125 126 TetherController::TetherController() { 127 mDnsNetId = 0; 128 mDaemonFd = -1; 129 mDaemonPid = 0; 130 if (inBpToolsMode()) { 131 enableForwarding(BP_TOOLS_MODE); 132 } else { 133 setIpFwdEnabled(); 134 } 135 } 136 137 TetherController::~TetherController() { 138 mInterfaces.clear(); 139 mDnsForwarders.clear(); 140 mForwardingRequests.clear(); 141 mFwdIfaces.clear(); 142 } 143 144 bool TetherController::setIpFwdEnabled() { 145 bool success = true; 146 const char* value = mForwardingRequests.empty() ? "0" : "1"; 147 ALOGD("Setting IP forward enable = %s", value); 148 success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value); 149 success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value); 150 return success; 151 } 152 153 bool TetherController::enableForwarding(const char* requester) { 154 // Don't return an error if this requester already requested forwarding. Only return errors for 155 // things that the caller caller needs to care about, such as "couldn't write to the file to 156 // enable forwarding". 157 mForwardingRequests.insert(requester); 158 return setIpFwdEnabled(); 159 } 160 161 bool TetherController::disableForwarding(const char* requester) { 162 mForwardingRequests.erase(requester); 163 return setIpFwdEnabled(); 164 } 165 166 size_t TetherController::forwardingRequestCount() { 167 return mForwardingRequests.size(); 168 } 169 170 int TetherController::startTethering(int num_addrs, char **dhcp_ranges) { 171 if (mDaemonPid != 0) { 172 ALOGE("Tethering already started"); 173 errno = EBUSY; 174 return -1; 175 } 176 177 ALOGD("Starting tethering services"); 178 179 pid_t pid; 180 int pipefd[2]; 181 182 if (pipe(pipefd) < 0) { 183 ALOGE("pipe failed (%s)", strerror(errno)); 184 return -1; 185 } 186 187 /* 188 * TODO: Create a monitoring thread to handle and restart 189 * the daemon if it exits prematurely 190 */ 191 if ((pid = fork()) < 0) { 192 ALOGE("fork failed (%s)", strerror(errno)); 193 close(pipefd[0]); 194 close(pipefd[1]); 195 return -1; 196 } 197 198 if (!pid) { 199 close(pipefd[1]); 200 if (pipefd[0] != STDIN_FILENO) { 201 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) { 202 ALOGE("dup2 failed (%s)", strerror(errno)); 203 return -1; 204 } 205 close(pipefd[0]); 206 } 207 208 Fwmark fwmark; 209 fwmark.netId = NetworkController::LOCAL_NET_ID; 210 fwmark.explicitlySelected = true; 211 fwmark.protectedFromVpn = true; 212 fwmark.permission = PERMISSION_SYSTEM; 213 char markStr[UINT32_HEX_STRLEN]; 214 snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue); 215 216 std::vector<const std::string> argVector = { 217 "/system/bin/dnsmasq", 218 "--keep-in-foreground", 219 "--no-resolv", 220 "--no-poll", 221 "--dhcp-authoritative", 222 // TODO: pipe through metered status from ConnService 223 "--dhcp-option-force=43,ANDROID_METERED", 224 "--pid-file", 225 "--listen-mark", markStr, 226 "--user", kDnsmasqUsername, 227 }; 228 229 for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) { 230 argVector.push_back( 231 StringPrintf("--dhcp-range=%s,%s,1h", 232 dhcp_ranges[addrIndex], dhcp_ranges[addrIndex+1])); 233 } 234 235 auto args = (char**)std::calloc(argVector.size() + 1, sizeof(char*)); 236 for (unsigned i = 0; i < argVector.size(); i++) { 237 args[i] = (char*)argVector[i].c_str(); 238 } 239 240 if (execv(args[0], args)) { 241 ALOGE("execv failed (%s)", strerror(errno)); 242 } 243 ALOGE("Should never get here!"); 244 _exit(-1); 245 } else { 246 close(pipefd[0]); 247 mDaemonPid = pid; 248 mDaemonFd = pipefd[1]; 249 configureForTethering(true); 250 applyDnsInterfaces(); 251 ALOGD("Tethering services running"); 252 } 253 254 return 0; 255 } 256 257 int TetherController::stopTethering() { 258 configureForTethering(false); 259 260 if (mDaemonPid == 0) { 261 ALOGE("Tethering already stopped"); 262 return 0; 263 } 264 265 ALOGD("Stopping tethering services"); 266 267 kill(mDaemonPid, SIGTERM); 268 waitpid(mDaemonPid, NULL, 0); 269 mDaemonPid = 0; 270 close(mDaemonFd); 271 mDaemonFd = -1; 272 ALOGD("Tethering services stopped"); 273 return 0; 274 } 275 276 bool TetherController::isTetheringStarted() { 277 return (mDaemonPid == 0 ? false : true); 278 } 279 280 #define MAX_CMD_SIZE 1024 281 282 int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) { 283 int i; 284 char daemonCmd[MAX_CMD_SIZE]; 285 286 Fwmark fwmark; 287 fwmark.netId = netId; 288 fwmark.explicitlySelected = true; 289 fwmark.protectedFromVpn = true; 290 fwmark.permission = PERMISSION_SYSTEM; 291 292 snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue); 293 int cmdLen = strlen(daemonCmd); 294 295 mDnsForwarders.clear(); 296 for (i = 0; i < numServers; i++) { 297 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]); 298 299 addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST }; 300 int ret = getaddrinfo(servers[i], NULL, &hints, &res); 301 freeaddrinfo(res); 302 if (ret) { 303 ALOGE("Failed to parse DNS server '%s'", servers[i]); 304 mDnsForwarders.clear(); 305 errno = EINVAL; 306 return -1; 307 } 308 309 cmdLen += (strlen(servers[i]) + 1); 310 if (cmdLen + 1 >= MAX_CMD_SIZE) { 311 ALOGD("Too many DNS servers listed"); 312 break; 313 } 314 315 strcat(daemonCmd, SEPARATOR); 316 strcat(daemonCmd, servers[i]); 317 mDnsForwarders.push_back(servers[i]); 318 } 319 320 mDnsNetId = netId; 321 if (mDaemonFd != -1) { 322 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 323 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 324 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 325 mDnsForwarders.clear(); 326 errno = EREMOTEIO; 327 return -1; 328 } 329 } 330 return 0; 331 } 332 333 unsigned TetherController::getDnsNetId() { 334 return mDnsNetId; 335 } 336 337 const std::list<std::string> &TetherController::getDnsForwarders() const { 338 return mDnsForwarders; 339 } 340 341 bool TetherController::applyDnsInterfaces() { 342 char daemonCmd[MAX_CMD_SIZE]; 343 344 strcpy(daemonCmd, "update_ifaces"); 345 int cmdLen = strlen(daemonCmd); 346 bool haveInterfaces = false; 347 348 for (const auto &ifname : mInterfaces) { 349 cmdLen += (ifname.size() + 1); 350 if (cmdLen + 1 >= MAX_CMD_SIZE) { 351 ALOGD("Too many DNS ifaces listed"); 352 break; 353 } 354 355 strcat(daemonCmd, SEPARATOR); 356 strcat(daemonCmd, ifname.c_str()); 357 haveInterfaces = true; 358 } 359 360 if ((mDaemonFd != -1) && haveInterfaces) { 361 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd); 362 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) { 363 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno)); 364 return false; 365 } 366 } 367 return true; 368 } 369 370 int TetherController::tetherInterface(const char *interface) { 371 ALOGD("tetherInterface(%s)", interface); 372 if (!isIfaceName(interface)) { 373 errno = ENOENT; 374 return -1; 375 } 376 377 if (!configureForIPv6Router(interface)) { 378 configureForIPv6Client(interface); 379 return -1; 380 } 381 mInterfaces.push_back(interface); 382 383 if (!applyDnsInterfaces()) { 384 mInterfaces.pop_back(); 385 configureForIPv6Client(interface); 386 return -1; 387 } else { 388 return 0; 389 } 390 } 391 392 int TetherController::untetherInterface(const char *interface) { 393 ALOGD("untetherInterface(%s)", interface); 394 395 for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) { 396 if (!strcmp(interface, it->c_str())) { 397 mInterfaces.erase(it); 398 399 configureForIPv6Client(interface); 400 return applyDnsInterfaces() ? 0 : -1; 401 } 402 } 403 errno = ENOENT; 404 return -1; 405 } 406 407 const std::list<std::string> &TetherController::getTetheredInterfaceList() const { 408 return mInterfaces; 409 } 410 411 int TetherController::setupIptablesHooks() { 412 int res; 413 res = setDefaults(); 414 if (res < 0) { 415 return res; 416 } 417 418 // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large 419 // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA. 420 // This is no longer optional and tethering will fail to start if it fails. 421 std::string mssRewriteCommand = StringPrintf( 422 "*mangle\n" 423 "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n" 424 "COMMIT\n", LOCAL_MANGLE_FORWARD); 425 426 // This is for tethering counters. This chain is reached via --goto, and then RETURNS. 427 std::string defaultCommands = StringPrintf( 428 "*filter\n" 429 ":%s -\n" 430 "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN); 431 432 res = iptablesRestoreFunction(V4, mssRewriteCommand, nullptr); 433 if (res < 0) { 434 return res; 435 } 436 437 res = iptablesRestoreFunction(V4V6, defaultCommands, nullptr); 438 if (res < 0) { 439 return res; 440 } 441 442 mFwdIfaces.clear(); 443 444 return 0; 445 } 446 447 int TetherController::setDefaults() { 448 std::string v4Cmd = StringPrintf( 449 "*filter\n" 450 ":%s -\n" 451 "-A %s -j DROP\n" 452 "COMMIT\n" 453 "*nat\n" 454 ":%s -\n" 455 "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING); 456 457 std::string v6Cmd = StringPrintf( 458 "*filter\n" 459 ":%s -\n" 460 "COMMIT\n" 461 "*raw\n" 462 ":%s -\n" 463 "COMMIT\n", LOCAL_FORWARD, LOCAL_RAW_PREROUTING); 464 465 int res = iptablesRestoreFunction(V4, v4Cmd, nullptr); 466 if (res < 0) { 467 return res; 468 } 469 470 res = iptablesRestoreFunction(V6, v6Cmd, nullptr); 471 if (res < 0) { 472 return res; 473 } 474 475 return 0; 476 } 477 478 int TetherController::enableNat(const char* intIface, const char* extIface) { 479 ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface); 480 481 if (!isIfaceName(intIface) || !isIfaceName(extIface)) { 482 errno = ENODEV; 483 return -1; 484 } 485 486 /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */ 487 if (!strcmp(intIface, extIface)) { 488 ALOGE("Duplicate interface specified: %s %s", intIface, extIface); 489 errno = EINVAL; 490 return -1; 491 } 492 493 if (isForwardingPairEnabled(intIface, extIface)) { 494 return 0; 495 } 496 497 // add this if we are the first enabled nat for this upstream 498 if (!isAnyForwardingEnabledOnUpstream(extIface)) { 499 std::vector<std::string> v4Cmds = { 500 "*nat", 501 StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface), 502 "COMMIT\n" 503 }; 504 505 if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) || 506 setupIPv6CountersChain()) { 507 ALOGE("Error setting postroute rule: iface=%s", extIface); 508 if (!isAnyForwardingPairEnabled()) { 509 // unwind what's been done, but don't care about success - what more could we do? 510 setDefaults(); 511 } 512 return -1; 513 } 514 } 515 516 if (setForwardRules(true, intIface, extIface) != 0) { 517 ALOGE("Error setting forward rules"); 518 if (!isAnyForwardingPairEnabled()) { 519 setDefaults(); 520 } 521 errno = ENODEV; 522 return -1; 523 } 524 525 return 0; 526 } 527 528 int TetherController::setupIPv6CountersChain() { 529 // Only add this if we are the first enabled nat 530 if (isAnyForwardingPairEnabled()) { 531 return 0; 532 } 533 534 /* 535 * IPv6 tethering doesn't need the state-based conntrack rules, so 536 * it unconditionally jumps to the tether counters chain all the time. 537 */ 538 std::vector<std::string> v6Cmds = { 539 "*filter", 540 StringPrintf("-A %s -g %s", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN), 541 "COMMIT\n" 542 }; 543 544 return iptablesRestoreFunction(V6, Join(v6Cmds, '\n'), nullptr); 545 } 546 547 // Gets a pointer to the ForwardingDownstream for an interface pair in the map, or nullptr 548 TetherController::ForwardingDownstream* TetherController::findForwardingDownstream( 549 const std::string& intIface, const std::string& extIface) { 550 auto extIfaceMatches = mFwdIfaces.equal_range(extIface); 551 for (auto it = extIfaceMatches.first; it != extIfaceMatches.second; ++it) { 552 if (it->second.iface == intIface) { 553 return &(it->second); 554 } 555 } 556 return nullptr; 557 } 558 559 void TetherController::addForwardingPair(const std::string& intIface, const std::string& extIface) { 560 ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface); 561 if (existingEntry != nullptr) { 562 existingEntry->active = true; 563 return; 564 } 565 566 mFwdIfaces.insert(std::pair<std::string, ForwardingDownstream>(extIface, { 567 .iface = intIface, 568 .active = true 569 })); 570 } 571 572 void TetherController::markForwardingPairDisabled( 573 const std::string& intIface, const std::string& extIface) { 574 ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface); 575 if (existingEntry == nullptr) { 576 return; 577 } 578 579 existingEntry->active = false; 580 } 581 582 bool TetherController::isForwardingPairEnabled( 583 const std::string& intIface, const std::string& extIface) { 584 ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface); 585 return existingEntry != nullptr && existingEntry->active; 586 } 587 588 bool TetherController::isAnyForwardingEnabledOnUpstream(const std::string& extIface) { 589 auto extIfaceMatches = mFwdIfaces.equal_range(extIface); 590 for (auto it = extIfaceMatches.first; it != extIfaceMatches.second; ++it) { 591 if (it->second.active) { 592 return true; 593 } 594 } 595 return false; 596 } 597 598 bool TetherController::isAnyForwardingPairEnabled() { 599 for (auto& it : mFwdIfaces) { 600 if (it.second.active) { 601 return true; 602 } 603 } 604 return false; 605 } 606 607 bool TetherController::tetherCountingRuleExists( 608 const std::string& iface1, const std::string& iface2) { 609 // A counting rule exists if NAT was ever enabled for this interface pair, so if the pair 610 // is in the map regardless of its active status. Rules are added both ways so we check with 611 // the 2 combinations. 612 return findForwardingDownstream(iface1, iface2) != nullptr 613 || findForwardingDownstream(iface2, iface1) != nullptr; 614 } 615 616 /* static */ 617 std::string TetherController::makeTetherCountingRule(const char *if1, const char *if2) { 618 return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2); 619 } 620 621 int TetherController::setForwardRules(bool add, const char *intIface, const char *extIface) { 622 const char *op = add ? "-A" : "-D"; 623 624 std::string rpfilterCmd = StringPrintf( 625 "*raw\n" 626 "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n" 627 "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface); 628 if (iptablesRestoreFunction(V6, rpfilterCmd, nullptr) == -1 && add) { 629 return -1; 630 } 631 632 std::vector<std::string> v4 = { 633 "*filter", 634 StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s", 635 op, LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN), 636 StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP", 637 op, LOCAL_FORWARD, intIface, extIface), 638 StringPrintf("%s %s -i %s -o %s -g %s", 639 op, LOCAL_FORWARD, intIface, extIface, LOCAL_TETHER_COUNTERS_CHAIN), 640 }; 641 642 std::vector<std::string> v6 = { 643 "*filter", 644 }; 645 646 // We only ever add tethering quota rules so that they stick. 647 if (add && !tetherCountingRuleExists(intIface, extIface)) { 648 v4.push_back(makeTetherCountingRule(intIface, extIface)); 649 v4.push_back(makeTetherCountingRule(extIface, intIface)); 650 v6.push_back(makeTetherCountingRule(intIface, extIface)); 651 v6.push_back(makeTetherCountingRule(extIface, intIface)); 652 } 653 654 // Always make sure the drop rule is at the end. 655 // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch 656 // every time, starting with ":tetherctrl_FORWARD -\n". This would likely be a bit simpler. 657 if (add) { 658 v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD)); 659 v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD)); 660 } 661 662 v4.push_back("COMMIT\n"); 663 v6.push_back("COMMIT\n"); 664 665 // We only add IPv6 rules here, never remove them. 666 if (iptablesRestoreFunction(V4, Join(v4, '\n'), nullptr) == -1 || 667 (add && iptablesRestoreFunction(V6, Join(v6, '\n'), nullptr) == -1)) { 668 // unwind what's been done, but don't care about success - what more could we do? 669 if (add) { 670 setForwardRules(false, intIface, extIface); 671 } 672 return -1; 673 } 674 675 if (add) { 676 addForwardingPair(intIface, extIface); 677 } else { 678 markForwardingPairDisabled(intIface, extIface); 679 } 680 681 return 0; 682 } 683 684 int TetherController::disableNat(const char* intIface, const char* extIface) { 685 if (!isIfaceName(intIface) || !isIfaceName(extIface)) { 686 errno = ENODEV; 687 return -1; 688 } 689 690 setForwardRules(false, intIface, extIface); 691 if (!isAnyForwardingPairEnabled()) { 692 setDefaults(); 693 } 694 return 0; 695 } 696 697 void TetherController::addStats(TetherStatsList& statsList, const TetherStats& stats) { 698 for (TetherStats& existing : statsList) { 699 if (existing.addStatsIfMatch(stats)) { 700 return; 701 } 702 } 703 // No match. Insert a new interface pair. 704 statsList.push_back(stats); 705 } 706 707 /* 708 * Parse the ptks and bytes out of: 709 * Chain tetherctrl_counters (4 references) 710 * pkts bytes target prot opt in out source destination 711 * 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0 712 * 27 2002 RETURN all -- rmnet0 wlan0 0.0.0.0/0 0.0.0.0/0 713 * 1040 107471 RETURN all -- bt-pan rmnet0 0.0.0.0/0 0.0.0.0/0 714 * 1450 1708806 RETURN all -- rmnet0 bt-pan 0.0.0.0/0 0.0.0.0/0 715 * or: 716 * Chain tetherctrl_counters (0 references) 717 * pkts bytes target prot opt in out source destination 718 * 0 0 RETURN all wlan0 rmnet_data0 ::/0 ::/0 719 * 0 0 RETURN all rmnet_data0 wlan0 ::/0 ::/0 720 * 721 */ 722 int TetherController::addForwardChainStats(TetherStatsList& statsList, 723 const std::string& statsOutput, 724 std::string &extraProcessingInfo) { 725 int res; 726 std::string statsLine; 727 char iface0[MAX_IPT_OUTPUT_LINE_LEN]; 728 char iface1[MAX_IPT_OUTPUT_LINE_LEN]; 729 char rest[MAX_IPT_OUTPUT_LINE_LEN]; 730 731 TetherStats stats; 732 const TetherStats empty; 733 const char *buffPtr; 734 int64_t packets, bytes; 735 736 std::stringstream stream(statsOutput); 737 738 // Skip headers. 739 for (int i = 0; i < 2; i++) { 740 std::getline(stream, statsLine, '\n'); 741 extraProcessingInfo += statsLine + "\n"; 742 if (statsLine.empty()) { 743 ALOGE("Empty header while parsing tethering stats"); 744 return -EREMOTEIO; 745 } 746 } 747 748 while (std::getline(stream, statsLine, '\n')) { 749 buffPtr = statsLine.c_str(); 750 751 /* Clean up, so a failed parse can still print info */ 752 iface0[0] = iface1[0] = rest[0] = packets = bytes = 0; 753 if (strstr(buffPtr, "0.0.0.0")) { 754 // IPv4 has -- indicating what to do with fragments... 755 // 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0 756 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all -- %s %s 0.%s", 757 &packets, &bytes, iface0, iface1, rest); 758 } else { 759 // ... but IPv6 does not. 760 // 26 2373 RETURN all wlan0 rmnet0 ::/0 ::/0 761 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all %s %s ::/%s", 762 &packets, &bytes, iface0, iface1, rest); 763 } 764 ALOGV("parse res=%d iface0=<%s> iface1=<%s> pkts=%" PRId64" bytes=%" PRId64" rest=<%s> orig line=<%s>", res, 765 iface0, iface1, packets, bytes, rest, buffPtr); 766 extraProcessingInfo += buffPtr; 767 extraProcessingInfo += "\n"; 768 769 if (res != 5) { 770 return -EREMOTEIO; 771 } 772 /* 773 * The following assumes that the 1st rule has in:extIface out:intIface, 774 * which is what TetherController sets up. 775 * The 1st matches rx, and sets up the pair for the tx side. 776 */ 777 if (!stats.intIface[0]) { 778 ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets); 779 stats.intIface = iface0; 780 stats.extIface = iface1; 781 stats.txPackets = packets; 782 stats.txBytes = bytes; 783 } else if (stats.intIface == iface1 && stats.extIface == iface0) { 784 ALOGV("0Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets); 785 stats.rxPackets = packets; 786 stats.rxBytes = bytes; 787 } 788 if (stats.rxBytes != -1 && stats.txBytes != -1) { 789 ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64, stats.rxBytes, stats.txBytes); 790 addStats(statsList, stats); 791 stats = empty; 792 } 793 } 794 795 /* It is always an error to find only one side of the stats. */ 796 if (((stats.rxBytes == -1) != (stats.txBytes == -1))) { 797 return -EREMOTEIO; 798 } 799 return 0; 800 } 801 802 StatusOr<TetherController::TetherStatsList> TetherController::getTetherStats() { 803 TetherStatsList statsList; 804 std::string parsedIptablesOutput; 805 806 for (const IptablesTarget target : {V4, V6}) { 807 std::string statsString; 808 if (int ret = iptablesRestoreFunction(target, GET_TETHER_STATS_COMMAND, &statsString)) { 809 return statusFromErrno(-ret, StringPrintf("failed to fetch tether stats (%d): %d", 810 target, ret)); 811 } 812 813 if (int ret = addForwardChainStats(statsList, statsString, parsedIptablesOutput)) { 814 return statusFromErrno(-ret, StringPrintf("failed to parse %s tether stats:\n%s", 815 target == V4 ? "IPv4": "IPv6", 816 parsedIptablesOutput.c_str())); 817 } 818 } 819 820 return statsList; 821 } 822 823 } // namespace net 824 } // namespace android 825