blob: 20e7ceeb226985d37ce97eb91f124015fbac6f5f [file] [log] [blame]
San Mehat9d10b342010-01-18 09:51:02 -08001/*
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
San Mehat9d10b342010-01-18 09:51:02 -080017#include <errno.h>
San Mehat18737842010-01-21 09:22:43 -080018#include <fcntl.h>
Lorenzo Colittia93126d2017-08-24 13:28:19 +090019#include <inttypes.h>
Lorenzo Colittic2841282015-11-25 22:13:57 +090020#include <netdb.h>
Olivier Baillyff2c0d82010-11-17 11:45:07 -080021#include <string.h>
San Mehat18737842010-01-21 09:22:43 -080022
San Mehat9d10b342010-01-18 09:51:02 -080023#include <sys/socket.h>
24#include <sys/stat.h>
San Mehat18737842010-01-21 09:22:43 -080025#include <sys/types.h>
26#include <sys/wait.h>
27
San Mehat9d10b342010-01-18 09:51:02 -080028#include <netinet/in.h>
29#include <arpa/inet.h>
30
Erik Kline5f0358b2018-02-16 15:08:09 +090031#include <array>
32#include <cstdlib>
waynema71a0b592018-11-21 13:31:34 +080033#include <regex>
Erik Kline5f0358b2018-02-16 15:08:09 +090034#include <string>
35#include <vector>
36
San Mehat9d10b342010-01-18 09:51:02 -080037#define LOG_TAG "TetherController"
Lorenzo Colittia93126d2017-08-24 13:28:19 +090038#include <android-base/strings.h>
39#include <android-base/stringprintf.h>
Kazuhiro Ondo6b858eb2011-06-24 20:31:03 -050040#include <cutils/properties.h>
Logan Chien3f461482018-04-23 14:31:32 +080041#include <log/log.h>
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +090042#include <netdutils/StatusOr.h>
San Mehat9d10b342010-01-18 09:51:02 -080043
Erik Klineb31fd692018-06-06 20:50:11 +090044#include "Controllers.h"
Lorenzo Colitti667c4772014-08-26 14:13:07 -070045#include "Fwmark.h"
JP Abgrall69261cb2014-06-19 18:35:24 -070046#include "NetdConstants.h"
Lorenzo Colitti667c4772014-08-26 14:13:07 -070047#include "Permission.h"
Erik Kline1d065ba2016-06-08 13:24:45 +090048#include "InterfaceController.h"
Lorenzo Colittie20a5262017-05-09 18:30:44 +090049#include "NetworkController.h"
Lorenzo Colittia93126d2017-08-24 13:28:19 +090050#include "ResponseCode.h"
San Mehat9d10b342010-01-18 09:51:02 -080051#include "TetherController.h"
52
Bernie Innocenti4debf3b2018-09-12 13:54:50 +090053namespace android {
54namespace net {
55
Lorenzo Colittia93126d2017-08-24 13:28:19 +090056using android::base::Join;
Lorenzo Colittia93126d2017-08-24 13:28:19 +090057using android::base::StringAppendF;
Erik Klineb31fd692018-06-06 20:50:11 +090058using android::base::StringPrintf;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +090059using android::netdutils::statusFromErrno;
Erik Klineb31fd692018-06-06 20:50:11 +090060using android::netdutils::StatusOr;
Lorenzo Colittia93126d2017-08-24 13:28:19 +090061
Lorenzo Colitti799625c2015-02-25 12:52:00 +090062namespace {
63
Erik Kline1d065ba2016-06-08 13:24:45 +090064const char BP_TOOLS_MODE[] = "bp-tools";
65const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
66const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
67const char SEPARATOR[] = "|";
Erik Kline93f9b222017-10-22 21:24:58 +090068constexpr const char kTcpBeLiberal[] = "/proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal";
Lorenzo Colitti799625c2015-02-25 12:52:00 +090069
Erik Kline5f0358b2018-02-16 15:08:09 +090070// Chosen to match AID_DNS_TETHER, as made "friendly" by fs_config_generator.py.
71constexpr const char kDnsmasqUsername[] = "dns_tether";
72
Lorenzo Colitti799625c2015-02-25 12:52:00 +090073bool writeToFile(const char* filename, const char* value) {
Nick Kralevichb95c60c2016-11-19 09:09:16 -080074 int fd = open(filename, O_WRONLY | O_CLOEXEC);
Nicolas Geoffrayafd40372015-03-16 11:58:06 +000075 if (fd < 0) {
76 ALOGE("Failed to open %s: %s", filename, strerror(errno));
77 return false;
78 }
79
80 const ssize_t len = strlen(value);
81 if (write(fd, value, len) != len) {
82 ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
83 close(fd);
84 return false;
85 }
86 close(fd);
87 return true;
Lorenzo Colitti799625c2015-02-25 12:52:00 +090088}
89
Erik Kline93f9b222017-10-22 21:24:58 +090090// TODO: Consider altering TCP and UDP timeouts as well.
91void configureForTethering(bool enabled) {
92 writeToFile(kTcpBeLiberal, enabled ? "1" : "0");
93}
94
Erik Kline1d065ba2016-06-08 13:24:45 +090095bool configureForIPv6Router(const char *interface) {
96 return (InterfaceController::setEnableIPv6(interface, 0) == 0)
97 && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
Erik Kline6cddf512016-08-09 15:28:42 +090098 && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0)
99 && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0)
Erik Kline1d065ba2016-06-08 13:24:45 +0900100 && (InterfaceController::setEnableIPv6(interface, 1) == 0);
101}
102
103void configureForIPv6Client(const char *interface) {
104 InterfaceController::setAcceptIPv6Ra(interface, 1);
Erik Kline6cddf512016-08-09 15:28:42 +0900105 InterfaceController::setAcceptIPv6Dad(interface, 1);
106 InterfaceController::setIPv6DadTransmits(interface, "1");
Erik Kline1d065ba2016-06-08 13:24:45 +0900107 InterfaceController::setEnableIPv6(interface, 0);
108}
109
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900110bool inBpToolsMode() {
111 // In BP tools mode, do not disable IP forwarding
112 char bootmode[PROPERTY_VALUE_MAX] = {0};
113 property_get("ro.bootmode", bootmode, "unknown");
114 return !strcmp(BP_TOOLS_MODE, bootmode);
115}
116
117} // namespace
118
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900119auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
120
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900121const 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
Erik Kline15079dd2018-05-18 23:10:56 +0900126int TetherController::DnsmasqState::sendCmd(int daemonFd, const std::string& cmd) {
127 if (cmd.empty()) return 0;
128
Erik Klineb31fd692018-06-06 20:50:11 +0900129 gLog.log("Sending update msg to dnsmasq [%s]", cmd.c_str());
Erik Kline15079dd2018-05-18 23:10:56 +0900130 // Send the trailing \0 as well.
131 if (write(daemonFd, cmd.c_str(), cmd.size() + 1) < 0) {
Erik Klineb31fd692018-06-06 20:50:11 +0900132 gLog.error("Failed to send update command to dnsmasq (%s)", strerror(errno));
Erik Kline15079dd2018-05-18 23:10:56 +0900133 errno = EREMOTEIO;
134 return -1;
135 }
136 return 0;
137}
138
139void TetherController::DnsmasqState::clear() {
140 update_ifaces_cmd.clear();
141 update_dns_cmd.clear();
142}
143
144int TetherController::DnsmasqState::sendAllState(int daemonFd) const {
145 return sendCmd(daemonFd, update_ifaces_cmd) | sendCmd(daemonFd, update_dns_cmd);
146}
147
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700148TetherController::TetherController() {
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900149 if (inBpToolsMode()) {
150 enableForwarding(BP_TOOLS_MODE);
151 } else {
152 setIpFwdEnabled();
153 }
San Mehat9d10b342010-01-18 09:51:02 -0800154}
155
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900156bool TetherController::setIpFwdEnabled() {
157 bool success = true;
Hugo Benichic4b3a0c2018-05-22 08:48:40 +0900158 bool disable = mForwardingRequests.empty();
159 const char* value = disable ? "0" : "1";
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900160 ALOGD("Setting IP forward enable = %s", value);
161 success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
162 success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
Hugo Benichic4b3a0c2018-05-22 08:48:40 +0900163 if (disable) {
164 // Turning off the forwarding sysconf in the kernel has the side effect
165 // of turning on ICMP redirect, which is a security hazard.
166 // Turn ICMP redirect back off immediately.
167 int rv = InterfaceController::disableIcmpRedirects();
168 success &= (rv == 0);
169 }
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900170 return success;
San Mehat9d10b342010-01-18 09:51:02 -0800171}
172
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900173bool TetherController::enableForwarding(const char* requester) {
174 // Don't return an error if this requester already requested forwarding. Only return errors for
175 // things that the caller caller needs to care about, such as "couldn't write to the file to
176 // enable forwarding".
177 mForwardingRequests.insert(requester);
178 return setIpFwdEnabled();
179}
San Mehat9d10b342010-01-18 09:51:02 -0800180
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900181bool TetherController::disableForwarding(const char* requester) {
182 mForwardingRequests.erase(requester);
183 return setIpFwdEnabled();
184}
San Mehat9d10b342010-01-18 09:51:02 -0800185
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900186size_t TetherController::forwardingRequestCount() {
187 return mForwardingRequests.size();
San Mehat9d10b342010-01-18 09:51:02 -0800188}
189
Erik Kline13fa01f2015-11-12 17:49:23 +0900190int TetherController::startTethering(int num_addrs, char **dhcp_ranges) {
San Mehat9d10b342010-01-18 09:51:02 -0800191 if (mDaemonPid != 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000192 ALOGE("Tethering already started");
San Mehat9d10b342010-01-18 09:51:02 -0800193 errno = EBUSY;
Luke Huangb5733d72018-08-21 17:17:19 +0800194 return -errno;
San Mehat9d10b342010-01-18 09:51:02 -0800195 }
196
Steve Block7b984e32011-12-20 16:22:42 +0000197 ALOGD("Starting tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800198
199 pid_t pid;
200 int pipefd[2];
201
202 if (pipe(pipefd) < 0) {
Luke Huangb5733d72018-08-21 17:17:19 +0800203 int res = errno;
Steve Block5ea0c052012-01-06 19:18:11 +0000204 ALOGE("pipe failed (%s)", strerror(errno));
Luke Huangb5733d72018-08-21 17:17:19 +0800205 return -res;
San Mehat9d10b342010-01-18 09:51:02 -0800206 }
207
208 /*
209 * TODO: Create a monitoring thread to handle and restart
210 * the daemon if it exits prematurely
211 */
212 if ((pid = fork()) < 0) {
Luke Huangb5733d72018-08-21 17:17:19 +0800213 int res = errno;
Steve Block5ea0c052012-01-06 19:18:11 +0000214 ALOGE("fork failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800215 close(pipefd[0]);
216 close(pipefd[1]);
Luke Huangb5733d72018-08-21 17:17:19 +0800217 return -res;
San Mehat9d10b342010-01-18 09:51:02 -0800218 }
219
220 if (!pid) {
221 close(pipefd[1]);
222 if (pipefd[0] != STDIN_FILENO) {
223 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
Luke Huangb5733d72018-08-21 17:17:19 +0800224 int res = errno;
Steve Block5ea0c052012-01-06 19:18:11 +0000225 ALOGE("dup2 failed (%s)", strerror(errno));
Luke Huangb5733d72018-08-21 17:17:19 +0800226 return -res;
San Mehat9d10b342010-01-18 09:51:02 -0800227 }
228 close(pipefd[0]);
229 }
San Mehat9d10b342010-01-18 09:51:02 -0800230
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900231 Fwmark fwmark;
232 fwmark.netId = NetworkController::LOCAL_NET_ID;
233 fwmark.explicitlySelected = true;
234 fwmark.protectedFromVpn = true;
235 fwmark.permission = PERMISSION_SYSTEM;
236 char markStr[UINT32_HEX_STRLEN];
237 snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue);
238
Erik Kline5f0358b2018-02-16 15:08:09 +0900239 std::vector<const std::string> argVector = {
240 "/system/bin/dnsmasq",
241 "--keep-in-foreground",
242 "--no-resolv",
243 "--no-poll",
244 "--dhcp-authoritative",
245 // TODO: pipe through metered status from ConnService
246 "--dhcp-option-force=43,ANDROID_METERED",
247 "--pid-file",
248 "--listen-mark", markStr,
249 "--user", kDnsmasqUsername,
250 };
San Mehat9d10b342010-01-18 09:51:02 -0800251
Remi NGUYEN VANedbf5f62018-08-06 15:03:18 +0900252 // DHCP server will be disabled if num_addrs == 0 and no --dhcp-range is passed.
Erik Kline13fa01f2015-11-12 17:49:23 +0900253 for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
Remi NGUYEN VANedbf5f62018-08-06 15:03:18 +0900254 argVector.push_back(StringPrintf("--dhcp-range=%s,%s,1h", dhcp_ranges[addrIndex],
255 dhcp_ranges[addrIndex + 1]));
Erik Kline5f0358b2018-02-16 15:08:09 +0900256 }
257
258 auto args = (char**)std::calloc(argVector.size() + 1, sizeof(char*));
259 for (unsigned i = 0; i < argVector.size(); i++) {
260 args[i] = (char*)argVector[i].c_str();
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700261 }
262
263 if (execv(args[0], args)) {
Erik Kline5f0358b2018-02-16 15:08:09 +0900264 ALOGE("execv failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800265 }
Steve Block5ea0c052012-01-06 19:18:11 +0000266 ALOGE("Should never get here!");
JP Abgrallce4f3792012-08-06 13:44:44 -0700267 _exit(-1);
San Mehat9d10b342010-01-18 09:51:02 -0800268 } else {
269 close(pipefd[0]);
270 mDaemonPid = pid;
271 mDaemonFd = pipefd[1];
Erik Kline93f9b222017-10-22 21:24:58 +0900272 configureForTethering(true);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800273 applyDnsInterfaces();
Steve Block7b984e32011-12-20 16:22:42 +0000274 ALOGD("Tethering services running");
San Mehat9d10b342010-01-18 09:51:02 -0800275 }
276
277 return 0;
278}
279
Luke Huangb5733d72018-08-21 17:17:19 +0800280std::vector<char*> TetherController::toCstrVec(const std::vector<std::string>& addrs) {
281 std::vector<char*> addrsCstrVec{};
282 addrsCstrVec.reserve(addrs.size());
283 for (const auto& addr : addrs) {
284 addrsCstrVec.push_back(const_cast<char*>(addr.data()));
285 }
286 return addrsCstrVec;
287}
288
289int TetherController::startTethering(const std::vector<std::string>& dhcpRanges) {
290 struct in_addr v4_addr;
291 for (const auto& dhcpRange : dhcpRanges) {
292 if (!inet_aton(dhcpRange.c_str(), &v4_addr)) {
293 return -EINVAL;
294 }
295 }
296 auto dhcp_ranges = toCstrVec(dhcpRanges);
297 return startTethering(dhcp_ranges.size(), dhcp_ranges.data());
298}
299
San Mehat9d10b342010-01-18 09:51:02 -0800300int TetherController::stopTethering() {
Erik Kline93f9b222017-10-22 21:24:58 +0900301 configureForTethering(false);
San Mehat9d10b342010-01-18 09:51:02 -0800302
303 if (mDaemonPid == 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000304 ALOGE("Tethering already stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800305 return 0;
306 }
307
Steve Block7b984e32011-12-20 16:22:42 +0000308 ALOGD("Stopping tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800309
310 kill(mDaemonPid, SIGTERM);
Yi Kongbdfd57e2018-07-25 13:26:10 -0700311 waitpid(mDaemonPid, nullptr, 0);
San Mehat9d10b342010-01-18 09:51:02 -0800312 mDaemonPid = 0;
313 close(mDaemonFd);
314 mDaemonFd = -1;
Erik Kline15079dd2018-05-18 23:10:56 +0900315 mDnsmasqState.clear();
Steve Block7b984e32011-12-20 16:22:42 +0000316 ALOGD("Tethering services stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800317 return 0;
318}
Matthew Xie19944102012-07-12 16:42:07 -0700319
San Mehat9d10b342010-01-18 09:51:02 -0800320bool TetherController::isTetheringStarted() {
321 return (mDaemonPid == 0 ? false : true);
322}
323
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900324// dnsmasq can't parse commands larger than this due to the fixed-size buffer
325// in check_android_listeners(). The receiving buffer is 1024 bytes long, but
326// dnsmasq reads up to 1023 bytes.
Bernie Innocenti45238a12018-12-04 14:57:48 +0900327const size_t MAX_CMD_SIZE = 1023;
Kenny Rootcf52faf2010-02-18 09:59:55 -0800328
Bernie Innocenti45238a12018-12-04 14:57:48 +0900329// TODO: convert callers to the overload taking a vector<string>
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700330int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700331 Fwmark fwmark;
332 fwmark.netId = netId;
333 fwmark.explicitlySelected = true;
334 fwmark.protectedFromVpn = true;
335 fwmark.permission = PERMISSION_SYSTEM;
336
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900337 std::string daemonCmd = StringPrintf("update_dns%s0x%x", SEPARATOR, fwmark.intValue);
San Mehat9d10b342010-01-18 09:51:02 -0800338
Erik Kline1d065ba2016-06-08 13:24:45 +0900339 mDnsForwarders.clear();
Bernie Innocenti45238a12018-12-04 14:57:48 +0900340 for (int i = 0; i < numServers; i++) {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700341 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800342
Lorenzo Colittic2841282015-11-25 22:13:57 +0900343 addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST };
Yi Kongbdfd57e2018-07-25 13:26:10 -0700344 int ret = getaddrinfo(servers[i], nullptr, &hints, &res);
Lorenzo Colittic2841282015-11-25 22:13:57 +0900345 freeaddrinfo(res);
346 if (ret) {
Steve Block5ea0c052012-01-06 19:18:11 +0000347 ALOGE("Failed to parse DNS server '%s'", servers[i]);
Erik Kline1d065ba2016-06-08 13:24:45 +0900348 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900349 errno = EINVAL;
Luke Huangb5733d72018-08-21 17:17:19 +0800350 return -errno;
San Mehat9d10b342010-01-18 09:51:02 -0800351 }
Kenny Rootcf52faf2010-02-18 09:59:55 -0800352
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900353 if (daemonCmd.size() + 1 + strlen(servers[i]) >= MAX_CMD_SIZE) {
354 ALOGE("Too many DNS servers listed");
Kenny Rootcf52faf2010-02-18 09:59:55 -0800355 break;
356 }
357
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900358 daemonCmd += SEPARATOR;
359 daemonCmd += servers[i];
Erik Kline1d065ba2016-06-08 13:24:45 +0900360 mDnsForwarders.push_back(servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800361 }
362
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700363 mDnsNetId = netId;
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900364 mDnsmasqState.update_dns_cmd = std::move(daemonCmd);
San Mehat9d10b342010-01-18 09:51:02 -0800365 if (mDaemonFd != -1) {
Erik Kline15079dd2018-05-18 23:10:56 +0900366 if (mDnsmasqState.sendAllState(mDaemonFd) != 0) {
Erik Kline1d065ba2016-06-08 13:24:45 +0900367 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900368 errno = EREMOTEIO;
Luke Huangb5733d72018-08-21 17:17:19 +0800369 return -errno;
San Mehat9d10b342010-01-18 09:51:02 -0800370 }
371 }
372 return 0;
373}
374
Luke Huangb5733d72018-08-21 17:17:19 +0800375int TetherController::setDnsForwarders(unsigned netId, const std::vector<std::string>& servers) {
376 struct in_addr v4_addr;
377 struct in6_addr v6_addr;
378 for (const auto& server : servers) {
379 if (!inet_pton(AF_INET, server.c_str(), &v4_addr) &&
380 !inet_pton(AF_INET6, server.c_str(), &v6_addr)) {
381 return -EINVAL;
382 }
383 }
384 auto dnsServers = toCstrVec(servers);
385 return setDnsForwarders(netId, dnsServers.data(), dnsServers.size());
386}
387
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700388unsigned TetherController::getDnsNetId() {
389 return mDnsNetId;
390}
391
Erik Kline1d065ba2016-06-08 13:24:45 +0900392const std::list<std::string> &TetherController::getDnsForwarders() const {
San Mehat9d10b342010-01-18 09:51:02 -0800393 return mDnsForwarders;
394}
395
Erik Kline1d065ba2016-06-08 13:24:45 +0900396bool TetherController::applyDnsInterfaces() {
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900397 std::string daemonCmd = "update_ifaces";
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800398 bool haveInterfaces = false;
399
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900400 for (const auto& ifname : mInterfaces) {
401 if (daemonCmd.size() + 1 + ifname.size() >= MAX_CMD_SIZE) {
402 ALOGE("Too many DNS servers listed");
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800403 break;
404 }
405
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900406 daemonCmd += SEPARATOR;
407 daemonCmd += ifname;
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800408 haveInterfaces = true;
409 }
410
Erik Kline15079dd2018-05-18 23:10:56 +0900411 if (!haveInterfaces) {
412 mDnsmasqState.update_ifaces_cmd.clear();
413 } else {
Bernie Innocenti15bb55c2018-06-03 16:19:51 +0900414 mDnsmasqState.update_ifaces_cmd = std::move(daemonCmd);
Erik Kline15079dd2018-05-18 23:10:56 +0900415 if (mDaemonFd != -1) return (mDnsmasqState.sendAllState(mDaemonFd) == 0);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800416 }
Erik Kline1d065ba2016-06-08 13:24:45 +0900417 return true;
San Mehat9d10b342010-01-18 09:51:02 -0800418}
419
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800420int TetherController::tetherInterface(const char *interface) {
421 ALOGD("tetherInterface(%s)", interface);
JP Abgrall69261cb2014-06-19 18:35:24 -0700422 if (!isIfaceName(interface)) {
423 errno = ENOENT;
Luke Huangb5733d72018-08-21 17:17:19 +0800424 return -errno;
JP Abgrall69261cb2014-06-19 18:35:24 -0700425 }
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800426
Erik Kline1d065ba2016-06-08 13:24:45 +0900427 if (!configureForIPv6Router(interface)) {
428 configureForIPv6Client(interface);
Luke Huangb5733d72018-08-21 17:17:19 +0800429 return -EREMOTEIO;
Erik Kline1d065ba2016-06-08 13:24:45 +0900430 }
431 mInterfaces.push_back(interface);
432
433 if (!applyDnsInterfaces()) {
434 mInterfaces.pop_back();
435 configureForIPv6Client(interface);
Luke Huangb5733d72018-08-21 17:17:19 +0800436 return -EREMOTEIO;
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800437 } else {
438 return 0;
439 }
440}
441
San Mehat9d10b342010-01-18 09:51:02 -0800442int TetherController::untetherInterface(const char *interface) {
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800443 ALOGD("untetherInterface(%s)", interface);
444
Erik Kline1d065ba2016-06-08 13:24:45 +0900445 for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
446 if (!strcmp(interface, it->c_str())) {
447 mInterfaces.erase(it);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800448
Erik Kline1d065ba2016-06-08 13:24:45 +0900449 configureForIPv6Client(interface);
Luke Huangb5733d72018-08-21 17:17:19 +0800450 return applyDnsInterfaces() ? 0 : -EREMOTEIO;
San Mehat9d10b342010-01-18 09:51:02 -0800451 }
452 }
453 errno = ENOENT;
Luke Huangb5733d72018-08-21 17:17:19 +0800454 return -errno;
San Mehat9d10b342010-01-18 09:51:02 -0800455}
456
Erik Kline1d065ba2016-06-08 13:24:45 +0900457const std::list<std::string> &TetherController::getTetheredInterfaceList() const {
San Mehat9d10b342010-01-18 09:51:02 -0800458 return mInterfaces;
459}
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900460
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900461int TetherController::setupIptablesHooks() {
462 int res;
463 res = setDefaults();
464 if (res < 0) {
465 return res;
466 }
467
468 // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large
469 // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA.
470 // This is no longer optional and tethering will fail to start if it fails.
471 std::string mssRewriteCommand = StringPrintf(
472 "*mangle\n"
473 "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n"
474 "COMMIT\n", LOCAL_MANGLE_FORWARD);
475
476 // This is for tethering counters. This chain is reached via --goto, and then RETURNS.
477 std::string defaultCommands = StringPrintf(
478 "*filter\n"
479 ":%s -\n"
480 "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN);
481
482 res = iptablesRestoreFunction(V4, mssRewriteCommand, nullptr);
483 if (res < 0) {
484 return res;
485 }
486
487 res = iptablesRestoreFunction(V4V6, defaultCommands, nullptr);
488 if (res < 0) {
489 return res;
490 }
491
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900492 mFwdIfaces.clear();
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900493
494 return 0;
495}
496
497int TetherController::setDefaults() {
498 std::string v4Cmd = StringPrintf(
499 "*filter\n"
500 ":%s -\n"
501 "-A %s -j DROP\n"
502 "COMMIT\n"
503 "*nat\n"
504 ":%s -\n"
505 "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING);
506
507 std::string v6Cmd = StringPrintf(
Luke Huangae038f82018-11-05 11:17:31 +0900508 "*filter\n"
509 ":%s -\n"
510 "COMMIT\n"
511 "*raw\n"
512 ":%s -\n"
513 "COMMIT\n",
514 LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900515
516 int res = iptablesRestoreFunction(V4, v4Cmd, nullptr);
517 if (res < 0) {
518 return res;
519 }
520
521 res = iptablesRestoreFunction(V6, v6Cmd, nullptr);
522 if (res < 0) {
523 return res;
524 }
525
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900526 return 0;
527}
528
529int TetherController::enableNat(const char* intIface, const char* extIface) {
530 ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
531
532 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
Luke Huang19b49c52018-10-22 12:12:05 +0900533 return -ENODEV;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900534 }
535
536 /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */
537 if (!strcmp(intIface, extIface)) {
538 ALOGE("Duplicate interface specified: %s %s", intIface, extIface);
Luke Huang19b49c52018-10-22 12:12:05 +0900539 return -EINVAL;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900540 }
541
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900542 if (isForwardingPairEnabled(intIface, extIface)) {
543 return 0;
544 }
545
546 // add this if we are the first enabled nat for this upstream
547 if (!isAnyForwardingEnabledOnUpstream(extIface)) {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900548 std::vector<std::string> v4Cmds = {
549 "*nat",
550 StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface),
551 "COMMIT\n"
552 };
553
Luke Huangae038f82018-11-05 11:17:31 +0900554 if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) || setupIPv6CountersChain() ||
555 setTetherGlobalAlertRule()) {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900556 ALOGE("Error setting postroute rule: iface=%s", extIface);
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900557 if (!isAnyForwardingPairEnabled()) {
558 // unwind what's been done, but don't care about success - what more could we do?
559 setDefaults();
560 }
Luke Huang19b49c52018-10-22 12:12:05 +0900561 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900562 }
563 }
564
565 if (setForwardRules(true, intIface, extIface) != 0) {
566 ALOGE("Error setting forward rules");
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900567 if (!isAnyForwardingPairEnabled()) {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900568 setDefaults();
569 }
Luke Huang19b49c52018-10-22 12:12:05 +0900570 return -ENODEV;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900571 }
572
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900573 return 0;
574}
575
Luke Huangae038f82018-11-05 11:17:31 +0900576int TetherController::setTetherGlobalAlertRule() {
577 // Only add this if we are the first enabled nat
578 if (isAnyForwardingPairEnabled()) {
579 return 0;
580 }
581 const std::string cmds =
582 "*filter\n" +
583 StringPrintf("-I %s -j %s\n", LOCAL_FORWARD, BandwidthController::LOCAL_GLOBAL_ALERT) +
584 "COMMIT\n";
585
586 return iptablesRestoreFunction(V4V6, cmds, nullptr);
587}
588
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900589int TetherController::setupIPv6CountersChain() {
590 // Only add this if we are the first enabled nat
591 if (isAnyForwardingPairEnabled()) {
592 return 0;
593 }
594
595 /*
596 * IPv6 tethering doesn't need the state-based conntrack rules, so
597 * it unconditionally jumps to the tether counters chain all the time.
598 */
Luke Huangae038f82018-11-05 11:17:31 +0900599 const std::string v6Cmds =
600 "*filter\n" +
601 StringPrintf("-A %s -g %s\n", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN) + "COMMIT\n";
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900602
Luke Huangae038f82018-11-05 11:17:31 +0900603 return iptablesRestoreFunction(V6, v6Cmds, nullptr);
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900604}
605
606// Gets a pointer to the ForwardingDownstream for an interface pair in the map, or nullptr
607TetherController::ForwardingDownstream* TetherController::findForwardingDownstream(
608 const std::string& intIface, const std::string& extIface) {
609 auto extIfaceMatches = mFwdIfaces.equal_range(extIface);
610 for (auto it = extIfaceMatches.first; it != extIfaceMatches.second; ++it) {
611 if (it->second.iface == intIface) {
612 return &(it->second);
613 }
614 }
615 return nullptr;
616}
617
618void TetherController::addForwardingPair(const std::string& intIface, const std::string& extIface) {
619 ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface);
620 if (existingEntry != nullptr) {
621 existingEntry->active = true;
622 return;
623 }
624
625 mFwdIfaces.insert(std::pair<std::string, ForwardingDownstream>(extIface, {
626 .iface = intIface,
627 .active = true
628 }));
629}
630
631void TetherController::markForwardingPairDisabled(
632 const std::string& intIface, const std::string& extIface) {
633 ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface);
634 if (existingEntry == nullptr) {
635 return;
636 }
637
638 existingEntry->active = false;
639}
640
641bool TetherController::isForwardingPairEnabled(
642 const std::string& intIface, const std::string& extIface) {
643 ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface);
644 return existingEntry != nullptr && existingEntry->active;
645}
646
647bool TetherController::isAnyForwardingEnabledOnUpstream(const std::string& extIface) {
648 auto extIfaceMatches = mFwdIfaces.equal_range(extIface);
649 for (auto it = extIfaceMatches.first; it != extIfaceMatches.second; ++it) {
650 if (it->second.active) {
651 return true;
652 }
653 }
654 return false;
655}
656
657bool TetherController::isAnyForwardingPairEnabled() {
658 for (auto& it : mFwdIfaces) {
659 if (it.second.active) {
660 return true;
661 }
662 }
663 return false;
664}
665
666bool TetherController::tetherCountingRuleExists(
667 const std::string& iface1, const std::string& iface2) {
668 // A counting rule exists if NAT was ever enabled for this interface pair, so if the pair
669 // is in the map regardless of its active status. Rules are added both ways so we check with
670 // the 2 combinations.
671 return findForwardingDownstream(iface1, iface2) != nullptr
672 || findForwardingDownstream(iface2, iface1) != nullptr;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900673}
674
675/* static */
676std::string TetherController::makeTetherCountingRule(const char *if1, const char *if2) {
677 return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2);
678}
679
680int TetherController::setForwardRules(bool add, const char *intIface, const char *extIface) {
681 const char *op = add ? "-A" : "-D";
682
683 std::string rpfilterCmd = StringPrintf(
684 "*raw\n"
685 "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
686 "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface);
687 if (iptablesRestoreFunction(V6, rpfilterCmd, nullptr) == -1 && add) {
Luke Huang19b49c52018-10-22 12:12:05 +0900688 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900689 }
690
691 std::vector<std::string> v4 = {
hiroaki.yokoyama04f2cb52018-06-13 18:47:30 +0900692 "*raw",
693 StringPrintf("%s %s -p tcp --dport 21 -i %s -j CT --helper ftp", op,
694 LOCAL_RAW_PREROUTING, intIface),
695 StringPrintf("%s %s -p tcp --dport 1723 -i %s -j CT --helper pptp", op,
696 LOCAL_RAW_PREROUTING, intIface),
697 "COMMIT",
698 "*filter",
699 StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s", op,
700 LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN),
701 StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP", op, LOCAL_FORWARD,
702 intIface, extIface),
703 StringPrintf("%s %s -i %s -o %s -g %s", op, LOCAL_FORWARD, intIface, extIface,
704 LOCAL_TETHER_COUNTERS_CHAIN),
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900705 };
706
707 std::vector<std::string> v6 = {
708 "*filter",
709 };
710
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900711 // We only ever add tethering quota rules so that they stick.
712 if (add && !tetherCountingRuleExists(intIface, extIface)) {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900713 v4.push_back(makeTetherCountingRule(intIface, extIface));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900714 v4.push_back(makeTetherCountingRule(extIface, intIface));
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900715 v6.push_back(makeTetherCountingRule(intIface, extIface));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900716 v6.push_back(makeTetherCountingRule(extIface, intIface));
717 }
718
719 // Always make sure the drop rule is at the end.
720 // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900721 // every time, starting with ":tetherctrl_FORWARD -\n". This would likely be a bit simpler.
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900722 if (add) {
723 v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD));
724 v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD));
725 }
726
727 v4.push_back("COMMIT\n");
728 v6.push_back("COMMIT\n");
729
730 // We only add IPv6 rules here, never remove them.
731 if (iptablesRestoreFunction(V4, Join(v4, '\n'), nullptr) == -1 ||
732 (add && iptablesRestoreFunction(V6, Join(v6, '\n'), nullptr) == -1)) {
733 // unwind what's been done, but don't care about success - what more could we do?
734 if (add) {
735 setForwardRules(false, intIface, extIface);
736 }
Luke Huang19b49c52018-10-22 12:12:05 +0900737 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900738 }
739
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900740 if (add) {
741 addForwardingPair(intIface, extIface);
742 } else {
743 markForwardingPairDisabled(intIface, extIface);
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900744 }
745
746 return 0;
747}
748
749int TetherController::disableNat(const char* intIface, const char* extIface) {
750 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
Luke Huangae038f82018-11-05 11:17:31 +0900751 errno = ENODEV;
752 return -errno;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900753 }
754
755 setForwardRules(false, intIface, extIface);
Remi NGUYEN VAN3b47c792018-03-20 14:44:12 +0900756 if (!isAnyForwardingPairEnabled()) {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900757 setDefaults();
758 }
759 return 0;
760}
761
762void TetherController::addStats(TetherStatsList& statsList, const TetherStats& stats) {
763 for (TetherStats& existing : statsList) {
764 if (existing.addStatsIfMatch(stats)) {
765 return;
766 }
767 }
768 // No match. Insert a new interface pair.
769 statsList.push_back(stats);
770}
771
772/*
773 * Parse the ptks and bytes out of:
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900774 * Chain tetherctrl_counters (4 references)
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900775 * pkts bytes target prot opt in out source destination
776 * 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
777 * 27 2002 RETURN all -- rmnet0 wlan0 0.0.0.0/0 0.0.0.0/0
778 * 1040 107471 RETURN all -- bt-pan rmnet0 0.0.0.0/0 0.0.0.0/0
779 * 1450 1708806 RETURN all -- rmnet0 bt-pan 0.0.0.0/0 0.0.0.0/0
780 * or:
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900781 * Chain tetherctrl_counters (0 references)
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900782 * pkts bytes target prot opt in out source destination
783 * 0 0 RETURN all wlan0 rmnet_data0 ::/0 ::/0
784 * 0 0 RETURN all rmnet_data0 wlan0 ::/0 ::/0
785 *
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900786 */
Lorenzo Colitti09353392017-08-24 14:20:32 +0900787int TetherController::addForwardChainStats(TetherStatsList& statsList,
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900788 const std::string& statsOutput,
789 std::string &extraProcessingInfo) {
waynema71a0b592018-11-21 13:31:34 +0800790 enum IndexOfIptChain {
791 ORIG_LINE,
792 PACKET_COUNTS,
793 BYTE_COUNTS,
794 HYPHEN,
795 IFACE0_NAME,
796 IFACE1_NAME,
797 SOURCE,
798 DESTINATION
799 };
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900800 TetherStats stats;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900801 const TetherStats empty;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900802
waynema71a0b592018-11-21 13:31:34 +0800803 static const std::string NUM = "(\\d+)";
804 static const std::string IFACE = "([^\\s]+)";
805 static const std::string DST = "(0.0.0.0/0|::/0)";
806 static const std::string COUNTERS = "\\s*" + NUM + "\\s+" + NUM +
807 " RETURN all( -- | )" + IFACE + "\\s+" + IFACE +
808 "\\s+" + DST + "\\s+" + DST;
809 static const std::regex IP_RE(COUNTERS);
Lorenzo Colitti09353392017-08-24 14:20:32 +0900810
waynema71a0b592018-11-21 13:31:34 +0800811 const std::vector<std::string> lines = base::Split(statsOutput, "\n");
812 int headerLine = 0;
813 for (const std::string& line : lines) {
814 // Skip headers.
815 if (headerLine < 2) {
816 if (line.empty()) {
817 ALOGV("Empty header while parsing tethering stats");
818 return -EREMOTEIO;
819 }
820 headerLine++;
821 continue;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900822 }
Lorenzo Colitti09353392017-08-24 14:20:32 +0900823
waynema71a0b592018-11-21 13:31:34 +0800824 if (line.empty()) continue;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900825
waynema71a0b592018-11-21 13:31:34 +0800826 extraProcessingInfo = line;
827 std::smatch matches;
828 if (!std::regex_search(line, matches, IP_RE)) return -EREMOTEIO;
829 // Here use IP_RE to distiguish IPv4 and IPv6 iptables.
830 // IPv4 has "--" indicating what to do with fragments...
831 // 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
832 // ... but IPv6 does not.
833 // 26 2373 RETURN all wlan0 rmnet0 ::/0 ::/0
834 // TODO: Replace strtoXX() calls with ParseUint() /ParseInt()
835 int64_t packets = strtoul(matches[PACKET_COUNTS].str().c_str(), nullptr, 10);
836 int64_t bytes = strtoul(matches[BYTE_COUNTS].str().c_str(), nullptr, 10);
837 std::string iface0 = matches[IFACE0_NAME].str();
838 std::string iface1 = matches[IFACE1_NAME].str();
839 std::string rest = matches[SOURCE].str();
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900840
waynema71a0b592018-11-21 13:31:34 +0800841 ALOGV("parse iface0=<%s> iface1=<%s> pkts=%" PRId64 " bytes=%" PRId64
842 " rest=<%s> orig line=<%s>",
843 iface0.c_str(), iface1.c_str(), packets, bytes, rest.c_str(), line.c_str());
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900844 /*
845 * The following assumes that the 1st rule has in:extIface out:intIface,
846 * which is what TetherController sets up.
Lorenzo Colitti09353392017-08-24 14:20:32 +0900847 * The 1st matches rx, and sets up the pair for the tx side.
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900848 */
Lorenzo Colitti09353392017-08-24 14:20:32 +0900849 if (!stats.intIface[0]) {
waynema71a0b592018-11-21 13:31:34 +0800850 ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64 " rx_packets=%" PRId64
851 " ", iface0.c_str(), iface1.c_str(), bytes, packets);
Lorenzo Colitti09353392017-08-24 14:20:32 +0900852 stats.intIface = iface0;
853 stats.extIface = iface1;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900854 stats.txPackets = packets;
855 stats.txBytes = bytes;
Lorenzo Colitti9a65ac62017-09-04 18:07:56 +0900856 } else if (stats.intIface == iface1 && stats.extIface == iface0) {
waynema71a0b592018-11-21 13:31:34 +0800857 ALOGV("0Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64 " rx_packets=%" PRId64
858 " ", iface0.c_str(), iface1.c_str(), bytes, packets);
Lorenzo Colitti9a65ac62017-09-04 18:07:56 +0900859 stats.rxPackets = packets;
860 stats.rxBytes = bytes;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900861 }
862 if (stats.rxBytes != -1 && stats.txBytes != -1) {
Lorenzo Colitti09353392017-08-24 14:20:32 +0900863 ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64, stats.rxBytes, stats.txBytes);
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900864 addStats(statsList, stats);
Lorenzo Colitti09353392017-08-24 14:20:32 +0900865 stats = empty;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900866 }
867 }
868
869 /* It is always an error to find only one side of the stats. */
Lorenzo Colitti38fd1362017-09-15 11:40:01 +0900870 if (((stats.rxBytes == -1) != (stats.txBytes == -1))) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900871 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900872 }
873 return 0;
874}
875
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900876StatusOr<TetherController::TetherStatsList> TetherController::getTetherStats() {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900877 TetherStatsList statsList;
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900878 std::string parsedIptablesOutput;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900879
880 for (const IptablesTarget target : {V4, V6}) {
881 std::string statsString;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900882 if (int ret = iptablesRestoreFunction(target, GET_TETHER_STATS_COMMAND, &statsString)) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900883 return statusFromErrno(-ret, StringPrintf("failed to fetch tether stats (%d): %d",
884 target, ret));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900885 }
886
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900887 if (int ret = addForwardChainStats(statsList, statsString, parsedIptablesOutput)) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900888 return statusFromErrno(-ret, StringPrintf("failed to parse %s tether stats:\n%s",
889 target == V4 ? "IPv4": "IPv6",
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900890 parsedIptablesOutput.c_str()));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900891 }
892 }
893
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900894 return statsList;
895}
896
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900897} // namespace net
898} // namespace android