1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker * Copyright (C) 2008 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker *
4*8542734aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker *
8*8542734aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker *
10*8542734aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker */
16*8542734aSAndroid Build Coastguard Worker
17*8542734aSAndroid Build Coastguard Worker #include <errno.h>
18*8542734aSAndroid Build Coastguard Worker #include <fcntl.h>
19*8542734aSAndroid Build Coastguard Worker #include <inttypes.h>
20*8542734aSAndroid Build Coastguard Worker #include <netdb.h>
21*8542734aSAndroid Build Coastguard Worker #include <spawn.h>
22*8542734aSAndroid Build Coastguard Worker #include <string.h>
23*8542734aSAndroid Build Coastguard Worker
24*8542734aSAndroid Build Coastguard Worker #include <sys/socket.h>
25*8542734aSAndroid Build Coastguard Worker #include <sys/stat.h>
26*8542734aSAndroid Build Coastguard Worker #include <sys/types.h>
27*8542734aSAndroid Build Coastguard Worker #include <sys/wait.h>
28*8542734aSAndroid Build Coastguard Worker
29*8542734aSAndroid Build Coastguard Worker #include <netinet/in.h>
30*8542734aSAndroid Build Coastguard Worker #include <arpa/inet.h>
31*8542734aSAndroid Build Coastguard Worker
32*8542734aSAndroid Build Coastguard Worker #include <array>
33*8542734aSAndroid Build Coastguard Worker #include <cstdlib>
34*8542734aSAndroid Build Coastguard Worker #include <regex>
35*8542734aSAndroid Build Coastguard Worker #include <string>
36*8542734aSAndroid Build Coastguard Worker #include <vector>
37*8542734aSAndroid Build Coastguard Worker
38*8542734aSAndroid Build Coastguard Worker #define LOG_TAG "TetherController"
39*8542734aSAndroid Build Coastguard Worker #include <android-base/scopeguard.h>
40*8542734aSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
41*8542734aSAndroid Build Coastguard Worker #include <android-base/strings.h>
42*8542734aSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
43*8542734aSAndroid Build Coastguard Worker #include <cutils/properties.h>
44*8542734aSAndroid Build Coastguard Worker #include <log/log.h>
45*8542734aSAndroid Build Coastguard Worker #include <net/if.h>
46*8542734aSAndroid Build Coastguard Worker #include <netdutils/DumpWriter.h>
47*8542734aSAndroid Build Coastguard Worker #include <netdutils/StatusOr.h>
48*8542734aSAndroid Build Coastguard Worker
49*8542734aSAndroid Build Coastguard Worker #include "Controllers.h"
50*8542734aSAndroid Build Coastguard Worker #include "Fwmark.h"
51*8542734aSAndroid Build Coastguard Worker #include "InterfaceController.h"
52*8542734aSAndroid Build Coastguard Worker #include "NetdConstants.h"
53*8542734aSAndroid Build Coastguard Worker #include "NetworkController.h"
54*8542734aSAndroid Build Coastguard Worker #include "Permission.h"
55*8542734aSAndroid Build Coastguard Worker #include "TcUtils.h"
56*8542734aSAndroid Build Coastguard Worker #include "TetherController.h"
57*8542734aSAndroid Build Coastguard Worker
58*8542734aSAndroid Build Coastguard Worker #include "android/net/TetherOffloadRuleParcel.h"
59*8542734aSAndroid Build Coastguard Worker
60*8542734aSAndroid Build Coastguard Worker namespace android {
61*8542734aSAndroid Build Coastguard Worker namespace net {
62*8542734aSAndroid Build Coastguard Worker
63*8542734aSAndroid Build Coastguard Worker using android::base::Join;
64*8542734aSAndroid Build Coastguard Worker using android::base::Pipe;
65*8542734aSAndroid Build Coastguard Worker using android::base::Result;
66*8542734aSAndroid Build Coastguard Worker using android::base::StringPrintf;
67*8542734aSAndroid Build Coastguard Worker using android::base::unique_fd;
68*8542734aSAndroid Build Coastguard Worker using android::netdutils::DumpWriter;
69*8542734aSAndroid Build Coastguard Worker using android::netdutils::ScopedIndent;
70*8542734aSAndroid Build Coastguard Worker using android::netdutils::statusFromErrno;
71*8542734aSAndroid Build Coastguard Worker using android::netdutils::StatusOr;
72*8542734aSAndroid Build Coastguard Worker
73*8542734aSAndroid Build Coastguard Worker namespace {
74*8542734aSAndroid Build Coastguard Worker
75*8542734aSAndroid Build Coastguard Worker const char BP_TOOLS_MODE[] = "bp-tools";
76*8542734aSAndroid Build Coastguard Worker const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
77*8542734aSAndroid Build Coastguard Worker const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
78*8542734aSAndroid Build Coastguard Worker const char SEPARATOR[] = "|";
79*8542734aSAndroid Build Coastguard Worker constexpr const char kTcpBeLiberal[] = "/proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal";
80*8542734aSAndroid Build Coastguard Worker
81*8542734aSAndroid Build Coastguard Worker // Chosen to match AID_DNS_TETHER, as made "friendly" by fs_config_generator.py.
82*8542734aSAndroid Build Coastguard Worker constexpr const char kDnsmasqUsername[] = "dns_tether";
83*8542734aSAndroid Build Coastguard Worker
writeToFile(const char * filename,const char * value)84*8542734aSAndroid Build Coastguard Worker bool writeToFile(const char* filename, const char* value) {
85*8542734aSAndroid Build Coastguard Worker int fd = open(filename, O_WRONLY | O_CLOEXEC);
86*8542734aSAndroid Build Coastguard Worker if (fd < 0) {
87*8542734aSAndroid Build Coastguard Worker ALOGE("Failed to open %s: %s", filename, strerror(errno));
88*8542734aSAndroid Build Coastguard Worker return false;
89*8542734aSAndroid Build Coastguard Worker }
90*8542734aSAndroid Build Coastguard Worker
91*8542734aSAndroid Build Coastguard Worker const ssize_t len = strlen(value);
92*8542734aSAndroid Build Coastguard Worker if (write(fd, value, len) != len) {
93*8542734aSAndroid Build Coastguard Worker ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
94*8542734aSAndroid Build Coastguard Worker close(fd);
95*8542734aSAndroid Build Coastguard Worker return false;
96*8542734aSAndroid Build Coastguard Worker }
97*8542734aSAndroid Build Coastguard Worker close(fd);
98*8542734aSAndroid Build Coastguard Worker return true;
99*8542734aSAndroid Build Coastguard Worker }
100*8542734aSAndroid Build Coastguard Worker
101*8542734aSAndroid Build Coastguard Worker // TODO: Consider altering TCP and UDP timeouts as well.
configureForTethering(bool enabled)102*8542734aSAndroid Build Coastguard Worker void configureForTethering(bool enabled) {
103*8542734aSAndroid Build Coastguard Worker writeToFile(kTcpBeLiberal, enabled ? "1" : "0");
104*8542734aSAndroid Build Coastguard Worker }
105*8542734aSAndroid Build Coastguard Worker
configureForIPv6Router(const char * interface)106*8542734aSAndroid Build Coastguard Worker bool configureForIPv6Router(const char *interface) {
107*8542734aSAndroid Build Coastguard Worker return (InterfaceController::setEnableIPv6(interface, 0) == 0)
108*8542734aSAndroid Build Coastguard Worker && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
109*8542734aSAndroid Build Coastguard Worker && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0)
110*8542734aSAndroid Build Coastguard Worker && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0)
111*8542734aSAndroid Build Coastguard Worker && (InterfaceController::setEnableIPv6(interface, 1) == 0);
112*8542734aSAndroid Build Coastguard Worker }
113*8542734aSAndroid Build Coastguard Worker
configureForIPv6Client(const char * interface)114*8542734aSAndroid Build Coastguard Worker void configureForIPv6Client(const char *interface) {
115*8542734aSAndroid Build Coastguard Worker InterfaceController::setAcceptIPv6Ra(interface, 1);
116*8542734aSAndroid Build Coastguard Worker InterfaceController::setAcceptIPv6Dad(interface, 1);
117*8542734aSAndroid Build Coastguard Worker InterfaceController::setIPv6DadTransmits(interface, "1");
118*8542734aSAndroid Build Coastguard Worker InterfaceController::setEnableIPv6(interface, 0);
119*8542734aSAndroid Build Coastguard Worker }
120*8542734aSAndroid Build Coastguard Worker
inBpToolsMode()121*8542734aSAndroid Build Coastguard Worker bool inBpToolsMode() {
122*8542734aSAndroid Build Coastguard Worker // In BP tools mode, do not disable IP forwarding
123*8542734aSAndroid Build Coastguard Worker char bootmode[PROPERTY_VALUE_MAX] = {0};
124*8542734aSAndroid Build Coastguard Worker property_get("ro.bootmode", bootmode, "unknown");
125*8542734aSAndroid Build Coastguard Worker return !strcmp(BP_TOOLS_MODE, bootmode);
126*8542734aSAndroid Build Coastguard Worker }
127*8542734aSAndroid Build Coastguard Worker
128*8542734aSAndroid Build Coastguard Worker } // namespace
129*8542734aSAndroid Build Coastguard Worker
130*8542734aSAndroid Build Coastguard Worker auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
131*8542734aSAndroid Build Coastguard Worker
132*8542734aSAndroid Build Coastguard Worker const std::string GET_TETHER_STATS_COMMAND = StringPrintf(
133*8542734aSAndroid Build Coastguard Worker "*filter\n"
134*8542734aSAndroid Build Coastguard Worker "-nvx -L %s\n"
135*8542734aSAndroid Build Coastguard Worker "COMMIT\n", android::net::TetherController::LOCAL_TETHER_COUNTERS_CHAIN);
136*8542734aSAndroid Build Coastguard Worker
sendCmd(int daemonFd,const std::string & cmd)137*8542734aSAndroid Build Coastguard Worker int TetherController::DnsmasqState::sendCmd(int daemonFd, const std::string& cmd) {
138*8542734aSAndroid Build Coastguard Worker if (cmd.empty()) return 0;
139*8542734aSAndroid Build Coastguard Worker
140*8542734aSAndroid Build Coastguard Worker gLog.log("Sending update msg to dnsmasq [%s]", cmd.c_str());
141*8542734aSAndroid Build Coastguard Worker // Send the trailing \0 as well.
142*8542734aSAndroid Build Coastguard Worker if (write(daemonFd, cmd.c_str(), cmd.size() + 1) < 0) {
143*8542734aSAndroid Build Coastguard Worker gLog.error("Failed to send update command to dnsmasq (%s)", strerror(errno));
144*8542734aSAndroid Build Coastguard Worker errno = EREMOTEIO;
145*8542734aSAndroid Build Coastguard Worker return -1;
146*8542734aSAndroid Build Coastguard Worker }
147*8542734aSAndroid Build Coastguard Worker return 0;
148*8542734aSAndroid Build Coastguard Worker }
149*8542734aSAndroid Build Coastguard Worker
clear()150*8542734aSAndroid Build Coastguard Worker void TetherController::DnsmasqState::clear() {
151*8542734aSAndroid Build Coastguard Worker update_ifaces_cmd.clear();
152*8542734aSAndroid Build Coastguard Worker update_dns_cmd.clear();
153*8542734aSAndroid Build Coastguard Worker }
154*8542734aSAndroid Build Coastguard Worker
sendAllState(int daemonFd) const155*8542734aSAndroid Build Coastguard Worker int TetherController::DnsmasqState::sendAllState(int daemonFd) const {
156*8542734aSAndroid Build Coastguard Worker return sendCmd(daemonFd, update_ifaces_cmd) | sendCmd(daemonFd, update_dns_cmd);
157*8542734aSAndroid Build Coastguard Worker }
158*8542734aSAndroid Build Coastguard Worker
TetherController()159*8542734aSAndroid Build Coastguard Worker TetherController::TetherController() {
160*8542734aSAndroid Build Coastguard Worker gLog.info("enter TetherController ctor");
161*8542734aSAndroid Build Coastguard Worker if (inBpToolsMode()) {
162*8542734aSAndroid Build Coastguard Worker enableForwarding(BP_TOOLS_MODE);
163*8542734aSAndroid Build Coastguard Worker } else {
164*8542734aSAndroid Build Coastguard Worker setIpFwdEnabled();
165*8542734aSAndroid Build Coastguard Worker }
166*8542734aSAndroid Build Coastguard Worker gLog.info("leave TetherController ctor");
167*8542734aSAndroid Build Coastguard Worker }
168*8542734aSAndroid Build Coastguard Worker
setIpFwdEnabled()169*8542734aSAndroid Build Coastguard Worker bool TetherController::setIpFwdEnabled() {
170*8542734aSAndroid Build Coastguard Worker bool success = true;
171*8542734aSAndroid Build Coastguard Worker bool disable = mForwardingRequests.empty();
172*8542734aSAndroid Build Coastguard Worker const char* value = disable ? "0" : "1";
173*8542734aSAndroid Build Coastguard Worker ALOGD("Setting IP forward enable = %s", value);
174*8542734aSAndroid Build Coastguard Worker success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
175*8542734aSAndroid Build Coastguard Worker success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
176*8542734aSAndroid Build Coastguard Worker if (disable) {
177*8542734aSAndroid Build Coastguard Worker // Turning off the forwarding sysconf in the kernel has the side effect
178*8542734aSAndroid Build Coastguard Worker // of turning on ICMP redirect, which is a security hazard.
179*8542734aSAndroid Build Coastguard Worker // Turn ICMP redirect back off immediately.
180*8542734aSAndroid Build Coastguard Worker int rv = InterfaceController::disableIcmpRedirects();
181*8542734aSAndroid Build Coastguard Worker success &= (rv == 0);
182*8542734aSAndroid Build Coastguard Worker }
183*8542734aSAndroid Build Coastguard Worker return success;
184*8542734aSAndroid Build Coastguard Worker }
185*8542734aSAndroid Build Coastguard Worker
enableForwarding(const char * requester)186*8542734aSAndroid Build Coastguard Worker bool TetherController::enableForwarding(const char* requester) {
187*8542734aSAndroid Build Coastguard Worker // Don't return an error if this requester already requested forwarding. Only return errors for
188*8542734aSAndroid Build Coastguard Worker // things that the caller caller needs to care about, such as "couldn't write to the file to
189*8542734aSAndroid Build Coastguard Worker // enable forwarding".
190*8542734aSAndroid Build Coastguard Worker mForwardingRequests.insert(requester);
191*8542734aSAndroid Build Coastguard Worker return setIpFwdEnabled();
192*8542734aSAndroid Build Coastguard Worker }
193*8542734aSAndroid Build Coastguard Worker
disableForwarding(const char * requester)194*8542734aSAndroid Build Coastguard Worker bool TetherController::disableForwarding(const char* requester) {
195*8542734aSAndroid Build Coastguard Worker mForwardingRequests.erase(requester);
196*8542734aSAndroid Build Coastguard Worker return setIpFwdEnabled();
197*8542734aSAndroid Build Coastguard Worker }
198*8542734aSAndroid Build Coastguard Worker
getIpfwdRequesterList() const199*8542734aSAndroid Build Coastguard Worker const std::set<std::string>& TetherController::getIpfwdRequesterList() const {
200*8542734aSAndroid Build Coastguard Worker return mForwardingRequests;
201*8542734aSAndroid Build Coastguard Worker }
202*8542734aSAndroid Build Coastguard Worker
startTethering(bool usingLegacyDnsProxy,int num_addrs,char ** dhcp_ranges)203*8542734aSAndroid Build Coastguard Worker int TetherController::startTethering(bool usingLegacyDnsProxy, int num_addrs, char** dhcp_ranges) {
204*8542734aSAndroid Build Coastguard Worker if (!usingLegacyDnsProxy && num_addrs == 0) {
205*8542734aSAndroid Build Coastguard Worker // Both DHCP and DnsProxy are disabled, we don't need to start dnsmasq
206*8542734aSAndroid Build Coastguard Worker configureForTethering(true);
207*8542734aSAndroid Build Coastguard Worker mIsTetheringStarted = true;
208*8542734aSAndroid Build Coastguard Worker return 0;
209*8542734aSAndroid Build Coastguard Worker }
210*8542734aSAndroid Build Coastguard Worker
211*8542734aSAndroid Build Coastguard Worker if (mIsTetheringStarted) {
212*8542734aSAndroid Build Coastguard Worker ALOGE("Tethering already started");
213*8542734aSAndroid Build Coastguard Worker errno = EBUSY;
214*8542734aSAndroid Build Coastguard Worker return -errno;
215*8542734aSAndroid Build Coastguard Worker }
216*8542734aSAndroid Build Coastguard Worker
217*8542734aSAndroid Build Coastguard Worker ALOGD("Starting tethering services");
218*8542734aSAndroid Build Coastguard Worker
219*8542734aSAndroid Build Coastguard Worker unique_fd pipeRead, pipeWrite;
220*8542734aSAndroid Build Coastguard Worker if (!Pipe(&pipeRead, &pipeWrite, O_CLOEXEC)) {
221*8542734aSAndroid Build Coastguard Worker int res = errno;
222*8542734aSAndroid Build Coastguard Worker ALOGE("pipe2() failed (%s)", strerror(errno));
223*8542734aSAndroid Build Coastguard Worker return -res;
224*8542734aSAndroid Build Coastguard Worker }
225*8542734aSAndroid Build Coastguard Worker
226*8542734aSAndroid Build Coastguard Worker // Set parameters
227*8542734aSAndroid Build Coastguard Worker Fwmark fwmark;
228*8542734aSAndroid Build Coastguard Worker fwmark.netId = NetworkController::LOCAL_NET_ID;
229*8542734aSAndroid Build Coastguard Worker fwmark.explicitlySelected = true;
230*8542734aSAndroid Build Coastguard Worker fwmark.protectedFromVpn = true;
231*8542734aSAndroid Build Coastguard Worker fwmark.permission = PERMISSION_SYSTEM;
232*8542734aSAndroid Build Coastguard Worker char markStr[UINT32_HEX_STRLEN];
233*8542734aSAndroid Build Coastguard Worker snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue);
234*8542734aSAndroid Build Coastguard Worker
235*8542734aSAndroid Build Coastguard Worker std::vector<std::string> argVector = {
236*8542734aSAndroid Build Coastguard Worker "/system/bin/dnsmasq",
237*8542734aSAndroid Build Coastguard Worker "--keep-in-foreground",
238*8542734aSAndroid Build Coastguard Worker "--no-resolv",
239*8542734aSAndroid Build Coastguard Worker "--no-poll",
240*8542734aSAndroid Build Coastguard Worker "--dhcp-authoritative",
241*8542734aSAndroid Build Coastguard Worker // TODO: pipe through metered status from ConnService
242*8542734aSAndroid Build Coastguard Worker "--dhcp-option-force=43,ANDROID_METERED",
243*8542734aSAndroid Build Coastguard Worker "--pid-file",
244*8542734aSAndroid Build Coastguard Worker "--listen-mark",
245*8542734aSAndroid Build Coastguard Worker markStr,
246*8542734aSAndroid Build Coastguard Worker "--user",
247*8542734aSAndroid Build Coastguard Worker kDnsmasqUsername,
248*8542734aSAndroid Build Coastguard Worker };
249*8542734aSAndroid Build Coastguard Worker
250*8542734aSAndroid Build Coastguard Worker if (!usingLegacyDnsProxy) {
251*8542734aSAndroid Build Coastguard Worker argVector.push_back("--port=0");
252*8542734aSAndroid Build Coastguard Worker }
253*8542734aSAndroid Build Coastguard Worker
254*8542734aSAndroid Build Coastguard Worker // DHCP server will be disabled if num_addrs == 0 and no --dhcp-range is passed.
255*8542734aSAndroid Build Coastguard Worker for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
256*8542734aSAndroid Build Coastguard Worker argVector.push_back(StringPrintf("--dhcp-range=%s,%s,1h", dhcp_ranges[addrIndex],
257*8542734aSAndroid Build Coastguard Worker dhcp_ranges[addrIndex + 1]));
258*8542734aSAndroid Build Coastguard Worker }
259*8542734aSAndroid Build Coastguard Worker
260*8542734aSAndroid Build Coastguard Worker std::vector<char*> args(argVector.size() + 1);
261*8542734aSAndroid Build Coastguard Worker for (unsigned i = 0; i < argVector.size(); i++) {
262*8542734aSAndroid Build Coastguard Worker args[i] = (char*)argVector[i].c_str();
263*8542734aSAndroid Build Coastguard Worker }
264*8542734aSAndroid Build Coastguard Worker
265*8542734aSAndroid Build Coastguard Worker /*
266*8542734aSAndroid Build Coastguard Worker * TODO: Create a monitoring thread to handle and restart
267*8542734aSAndroid Build Coastguard Worker * the daemon if it exits prematurely
268*8542734aSAndroid Build Coastguard Worker */
269*8542734aSAndroid Build Coastguard Worker
270*8542734aSAndroid Build Coastguard Worker // Note that don't modify any memory between vfork and execv.
271*8542734aSAndroid Build Coastguard Worker // Changing state of file descriptors would be fine. See posix_spawn_file_actions_add*
272*8542734aSAndroid Build Coastguard Worker // dup2 creates fd without CLOEXEC, dnsmasq will receive commands through the
273*8542734aSAndroid Build Coastguard Worker // duplicated fd.
274*8542734aSAndroid Build Coastguard Worker posix_spawn_file_actions_t fa;
275*8542734aSAndroid Build Coastguard Worker int res = posix_spawn_file_actions_init(&fa);
276*8542734aSAndroid Build Coastguard Worker if (res) {
277*8542734aSAndroid Build Coastguard Worker ALOGE("posix_spawn_file_actions_init failed (%s)", strerror(res));
278*8542734aSAndroid Build Coastguard Worker return -res;
279*8542734aSAndroid Build Coastguard Worker }
280*8542734aSAndroid Build Coastguard Worker const android::base::ScopeGuard faGuard = [&] { posix_spawn_file_actions_destroy(&fa); };
281*8542734aSAndroid Build Coastguard Worker res = posix_spawn_file_actions_adddup2(&fa, pipeRead.get(), STDIN_FILENO);
282*8542734aSAndroid Build Coastguard Worker if (res) {
283*8542734aSAndroid Build Coastguard Worker ALOGE("posix_spawn_file_actions_adddup2 failed (%s)", strerror(res));
284*8542734aSAndroid Build Coastguard Worker return -res;
285*8542734aSAndroid Build Coastguard Worker }
286*8542734aSAndroid Build Coastguard Worker
287*8542734aSAndroid Build Coastguard Worker posix_spawnattr_t attr;
288*8542734aSAndroid Build Coastguard Worker res = posix_spawnattr_init(&attr);
289*8542734aSAndroid Build Coastguard Worker if (res) {
290*8542734aSAndroid Build Coastguard Worker ALOGE("posix_spawnattr_init failed (%s)", strerror(res));
291*8542734aSAndroid Build Coastguard Worker return -res;
292*8542734aSAndroid Build Coastguard Worker }
293*8542734aSAndroid Build Coastguard Worker const android::base::ScopeGuard attrGuard = [&] { posix_spawnattr_destroy(&attr); };
294*8542734aSAndroid Build Coastguard Worker res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_USEVFORK | POSIX_SPAWN_CLOEXEC_DEFAULT);
295*8542734aSAndroid Build Coastguard Worker if (res) {
296*8542734aSAndroid Build Coastguard Worker ALOGE("posix_spawnattr_setflags failed (%s)", strerror(res));
297*8542734aSAndroid Build Coastguard Worker return -res;
298*8542734aSAndroid Build Coastguard Worker }
299*8542734aSAndroid Build Coastguard Worker
300*8542734aSAndroid Build Coastguard Worker pid_t pid;
301*8542734aSAndroid Build Coastguard Worker res = posix_spawn(&pid, args[0], &fa, &attr, &args[0], nullptr);
302*8542734aSAndroid Build Coastguard Worker if (res) {
303*8542734aSAndroid Build Coastguard Worker ALOGE("posix_spawn failed (%s)", strerror(res));
304*8542734aSAndroid Build Coastguard Worker return -res;
305*8542734aSAndroid Build Coastguard Worker }
306*8542734aSAndroid Build Coastguard Worker mDaemonPid = pid;
307*8542734aSAndroid Build Coastguard Worker mDaemonFd = pipeWrite.release();
308*8542734aSAndroid Build Coastguard Worker configureForTethering(true);
309*8542734aSAndroid Build Coastguard Worker mIsTetheringStarted = true;
310*8542734aSAndroid Build Coastguard Worker applyDnsInterfaces();
311*8542734aSAndroid Build Coastguard Worker ALOGD("Tethering services running");
312*8542734aSAndroid Build Coastguard Worker
313*8542734aSAndroid Build Coastguard Worker return 0;
314*8542734aSAndroid Build Coastguard Worker }
315*8542734aSAndroid Build Coastguard Worker
toCstrVec(const std::vector<std::string> & addrs)316*8542734aSAndroid Build Coastguard Worker std::vector<char*> TetherController::toCstrVec(const std::vector<std::string>& addrs) {
317*8542734aSAndroid Build Coastguard Worker std::vector<char*> addrsCstrVec{};
318*8542734aSAndroid Build Coastguard Worker addrsCstrVec.reserve(addrs.size());
319*8542734aSAndroid Build Coastguard Worker for (const auto& addr : addrs) {
320*8542734aSAndroid Build Coastguard Worker addrsCstrVec.push_back(const_cast<char*>(addr.data()));
321*8542734aSAndroid Build Coastguard Worker }
322*8542734aSAndroid Build Coastguard Worker return addrsCstrVec;
323*8542734aSAndroid Build Coastguard Worker }
324*8542734aSAndroid Build Coastguard Worker
startTethering(bool usingLegacyDnsProxy,const std::vector<std::string> & dhcpRanges)325*8542734aSAndroid Build Coastguard Worker int TetherController::startTethering(bool usingLegacyDnsProxy,
326*8542734aSAndroid Build Coastguard Worker const std::vector<std::string>& dhcpRanges) {
327*8542734aSAndroid Build Coastguard Worker struct in_addr v4_addr;
328*8542734aSAndroid Build Coastguard Worker for (const auto& dhcpRange : dhcpRanges) {
329*8542734aSAndroid Build Coastguard Worker if (!inet_aton(dhcpRange.c_str(), &v4_addr)) {
330*8542734aSAndroid Build Coastguard Worker return -EINVAL;
331*8542734aSAndroid Build Coastguard Worker }
332*8542734aSAndroid Build Coastguard Worker }
333*8542734aSAndroid Build Coastguard Worker auto dhcp_ranges = toCstrVec(dhcpRanges);
334*8542734aSAndroid Build Coastguard Worker return startTethering(usingLegacyDnsProxy, dhcp_ranges.size(), dhcp_ranges.data());
335*8542734aSAndroid Build Coastguard Worker }
336*8542734aSAndroid Build Coastguard Worker
stopTethering()337*8542734aSAndroid Build Coastguard Worker int TetherController::stopTethering() {
338*8542734aSAndroid Build Coastguard Worker configureForTethering(false);
339*8542734aSAndroid Build Coastguard Worker
340*8542734aSAndroid Build Coastguard Worker if (!mIsTetheringStarted) {
341*8542734aSAndroid Build Coastguard Worker ALOGE("Tethering already stopped");
342*8542734aSAndroid Build Coastguard Worker return 0;
343*8542734aSAndroid Build Coastguard Worker }
344*8542734aSAndroid Build Coastguard Worker
345*8542734aSAndroid Build Coastguard Worker mIsTetheringStarted = false;
346*8542734aSAndroid Build Coastguard Worker // dnsmasq is not started
347*8542734aSAndroid Build Coastguard Worker if (mDaemonPid == 0) {
348*8542734aSAndroid Build Coastguard Worker return 0;
349*8542734aSAndroid Build Coastguard Worker }
350*8542734aSAndroid Build Coastguard Worker
351*8542734aSAndroid Build Coastguard Worker ALOGD("Stopping tethering services");
352*8542734aSAndroid Build Coastguard Worker
353*8542734aSAndroid Build Coastguard Worker ::stopProcess(mDaemonPid, "tethering(dnsmasq)");
354*8542734aSAndroid Build Coastguard Worker mDaemonPid = 0;
355*8542734aSAndroid Build Coastguard Worker close(mDaemonFd);
356*8542734aSAndroid Build Coastguard Worker mDaemonFd = -1;
357*8542734aSAndroid Build Coastguard Worker mDnsmasqState.clear();
358*8542734aSAndroid Build Coastguard Worker ALOGD("Tethering services stopped");
359*8542734aSAndroid Build Coastguard Worker return 0;
360*8542734aSAndroid Build Coastguard Worker }
361*8542734aSAndroid Build Coastguard Worker
isTetheringStarted()362*8542734aSAndroid Build Coastguard Worker bool TetherController::isTetheringStarted() {
363*8542734aSAndroid Build Coastguard Worker return mIsTetheringStarted;
364*8542734aSAndroid Build Coastguard Worker }
365*8542734aSAndroid Build Coastguard Worker
366*8542734aSAndroid Build Coastguard Worker // dnsmasq can't parse commands larger than this due to the fixed-size buffer
367*8542734aSAndroid Build Coastguard Worker // in check_android_listeners(). The receiving buffer is 1024 bytes long, but
368*8542734aSAndroid Build Coastguard Worker // dnsmasq reads up to 1023 bytes.
369*8542734aSAndroid Build Coastguard Worker const size_t MAX_CMD_SIZE = 1023;
370*8542734aSAndroid Build Coastguard Worker
371*8542734aSAndroid Build Coastguard Worker // TODO: Remove overload function and update this after NDC migration.
setDnsForwarders(unsigned netId,char ** servers,int numServers)372*8542734aSAndroid Build Coastguard Worker int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
373*8542734aSAndroid Build Coastguard Worker Fwmark fwmark;
374*8542734aSAndroid Build Coastguard Worker fwmark.netId = netId;
375*8542734aSAndroid Build Coastguard Worker fwmark.explicitlySelected = true;
376*8542734aSAndroid Build Coastguard Worker fwmark.protectedFromVpn = true;
377*8542734aSAndroid Build Coastguard Worker fwmark.permission = PERMISSION_SYSTEM;
378*8542734aSAndroid Build Coastguard Worker
379*8542734aSAndroid Build Coastguard Worker std::string daemonCmd = StringPrintf("update_dns%s0x%x", SEPARATOR, fwmark.intValue);
380*8542734aSAndroid Build Coastguard Worker
381*8542734aSAndroid Build Coastguard Worker mDnsForwarders.clear();
382*8542734aSAndroid Build Coastguard Worker for (int i = 0; i < numServers; i++) {
383*8542734aSAndroid Build Coastguard Worker ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
384*8542734aSAndroid Build Coastguard Worker
385*8542734aSAndroid Build Coastguard Worker addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST };
386*8542734aSAndroid Build Coastguard Worker int ret = getaddrinfo(servers[i], nullptr, &hints, &res);
387*8542734aSAndroid Build Coastguard Worker freeaddrinfo(res);
388*8542734aSAndroid Build Coastguard Worker if (ret) {
389*8542734aSAndroid Build Coastguard Worker ALOGE("Failed to parse DNS server '%s'", servers[i]);
390*8542734aSAndroid Build Coastguard Worker mDnsForwarders.clear();
391*8542734aSAndroid Build Coastguard Worker errno = EINVAL;
392*8542734aSAndroid Build Coastguard Worker return -errno;
393*8542734aSAndroid Build Coastguard Worker }
394*8542734aSAndroid Build Coastguard Worker
395*8542734aSAndroid Build Coastguard Worker if (daemonCmd.size() + 1 + strlen(servers[i]) >= MAX_CMD_SIZE) {
396*8542734aSAndroid Build Coastguard Worker ALOGE("Too many DNS servers listed");
397*8542734aSAndroid Build Coastguard Worker break;
398*8542734aSAndroid Build Coastguard Worker }
399*8542734aSAndroid Build Coastguard Worker
400*8542734aSAndroid Build Coastguard Worker daemonCmd += SEPARATOR;
401*8542734aSAndroid Build Coastguard Worker daemonCmd += servers[i];
402*8542734aSAndroid Build Coastguard Worker mDnsForwarders.push_back(servers[i]);
403*8542734aSAndroid Build Coastguard Worker }
404*8542734aSAndroid Build Coastguard Worker
405*8542734aSAndroid Build Coastguard Worker mDnsNetId = netId;
406*8542734aSAndroid Build Coastguard Worker mDnsmasqState.update_dns_cmd = std::move(daemonCmd);
407*8542734aSAndroid Build Coastguard Worker if (mDaemonFd != -1) {
408*8542734aSAndroid Build Coastguard Worker if (mDnsmasqState.sendAllState(mDaemonFd) != 0) {
409*8542734aSAndroid Build Coastguard Worker mDnsForwarders.clear();
410*8542734aSAndroid Build Coastguard Worker errno = EREMOTEIO;
411*8542734aSAndroid Build Coastguard Worker return -errno;
412*8542734aSAndroid Build Coastguard Worker }
413*8542734aSAndroid Build Coastguard Worker }
414*8542734aSAndroid Build Coastguard Worker return 0;
415*8542734aSAndroid Build Coastguard Worker }
416*8542734aSAndroid Build Coastguard Worker
setDnsForwarders(unsigned netId,const std::vector<std::string> & servers)417*8542734aSAndroid Build Coastguard Worker int TetherController::setDnsForwarders(unsigned netId, const std::vector<std::string>& servers) {
418*8542734aSAndroid Build Coastguard Worker auto dnsServers = toCstrVec(servers);
419*8542734aSAndroid Build Coastguard Worker return setDnsForwarders(netId, dnsServers.data(), dnsServers.size());
420*8542734aSAndroid Build Coastguard Worker }
421*8542734aSAndroid Build Coastguard Worker
getDnsNetId()422*8542734aSAndroid Build Coastguard Worker unsigned TetherController::getDnsNetId() {
423*8542734aSAndroid Build Coastguard Worker return mDnsNetId;
424*8542734aSAndroid Build Coastguard Worker }
425*8542734aSAndroid Build Coastguard Worker
getDnsForwarders() const426*8542734aSAndroid Build Coastguard Worker const std::list<std::string> &TetherController::getDnsForwarders() const {
427*8542734aSAndroid Build Coastguard Worker return mDnsForwarders;
428*8542734aSAndroid Build Coastguard Worker }
429*8542734aSAndroid Build Coastguard Worker
applyDnsInterfaces()430*8542734aSAndroid Build Coastguard Worker bool TetherController::applyDnsInterfaces() {
431*8542734aSAndroid Build Coastguard Worker std::string daemonCmd = "update_ifaces";
432*8542734aSAndroid Build Coastguard Worker bool haveInterfaces = false;
433*8542734aSAndroid Build Coastguard Worker
434*8542734aSAndroid Build Coastguard Worker for (const auto& ifname : mInterfaces) {
435*8542734aSAndroid Build Coastguard Worker if (daemonCmd.size() + 1 + ifname.size() >= MAX_CMD_SIZE) {
436*8542734aSAndroid Build Coastguard Worker ALOGE("Too many DNS servers listed");
437*8542734aSAndroid Build Coastguard Worker break;
438*8542734aSAndroid Build Coastguard Worker }
439*8542734aSAndroid Build Coastguard Worker
440*8542734aSAndroid Build Coastguard Worker daemonCmd += SEPARATOR;
441*8542734aSAndroid Build Coastguard Worker daemonCmd += ifname;
442*8542734aSAndroid Build Coastguard Worker haveInterfaces = true;
443*8542734aSAndroid Build Coastguard Worker }
444*8542734aSAndroid Build Coastguard Worker
445*8542734aSAndroid Build Coastguard Worker if (!haveInterfaces) {
446*8542734aSAndroid Build Coastguard Worker mDnsmasqState.update_ifaces_cmd.clear();
447*8542734aSAndroid Build Coastguard Worker } else {
448*8542734aSAndroid Build Coastguard Worker mDnsmasqState.update_ifaces_cmd = std::move(daemonCmd);
449*8542734aSAndroid Build Coastguard Worker if (mDaemonFd != -1) return (mDnsmasqState.sendAllState(mDaemonFd) == 0);
450*8542734aSAndroid Build Coastguard Worker }
451*8542734aSAndroid Build Coastguard Worker return true;
452*8542734aSAndroid Build Coastguard Worker }
453*8542734aSAndroid Build Coastguard Worker
tetherInterface(const char * interface)454*8542734aSAndroid Build Coastguard Worker int TetherController::tetherInterface(const char *interface) {
455*8542734aSAndroid Build Coastguard Worker ALOGD("tetherInterface(%s)", interface);
456*8542734aSAndroid Build Coastguard Worker if (!isIfaceName(interface)) {
457*8542734aSAndroid Build Coastguard Worker errno = ENOENT;
458*8542734aSAndroid Build Coastguard Worker return -errno;
459*8542734aSAndroid Build Coastguard Worker }
460*8542734aSAndroid Build Coastguard Worker
461*8542734aSAndroid Build Coastguard Worker if (!configureForIPv6Router(interface)) {
462*8542734aSAndroid Build Coastguard Worker configureForIPv6Client(interface);
463*8542734aSAndroid Build Coastguard Worker return -EREMOTEIO;
464*8542734aSAndroid Build Coastguard Worker }
465*8542734aSAndroid Build Coastguard Worker mInterfaces.push_back(interface);
466*8542734aSAndroid Build Coastguard Worker
467*8542734aSAndroid Build Coastguard Worker if (!applyDnsInterfaces()) {
468*8542734aSAndroid Build Coastguard Worker mInterfaces.pop_back();
469*8542734aSAndroid Build Coastguard Worker configureForIPv6Client(interface);
470*8542734aSAndroid Build Coastguard Worker return -EREMOTEIO;
471*8542734aSAndroid Build Coastguard Worker } else {
472*8542734aSAndroid Build Coastguard Worker return 0;
473*8542734aSAndroid Build Coastguard Worker }
474*8542734aSAndroid Build Coastguard Worker }
475*8542734aSAndroid Build Coastguard Worker
untetherInterface(const char * interface)476*8542734aSAndroid Build Coastguard Worker int TetherController::untetherInterface(const char *interface) {
477*8542734aSAndroid Build Coastguard Worker ALOGD("untetherInterface(%s)", interface);
478*8542734aSAndroid Build Coastguard Worker
479*8542734aSAndroid Build Coastguard Worker for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
480*8542734aSAndroid Build Coastguard Worker if (!strcmp(interface, it->c_str())) {
481*8542734aSAndroid Build Coastguard Worker mInterfaces.erase(it);
482*8542734aSAndroid Build Coastguard Worker
483*8542734aSAndroid Build Coastguard Worker configureForIPv6Client(interface);
484*8542734aSAndroid Build Coastguard Worker return applyDnsInterfaces() ? 0 : -EREMOTEIO;
485*8542734aSAndroid Build Coastguard Worker }
486*8542734aSAndroid Build Coastguard Worker }
487*8542734aSAndroid Build Coastguard Worker errno = ENOENT;
488*8542734aSAndroid Build Coastguard Worker return -errno;
489*8542734aSAndroid Build Coastguard Worker }
490*8542734aSAndroid Build Coastguard Worker
getTetheredInterfaceList() const491*8542734aSAndroid Build Coastguard Worker const std::list<std::string> &TetherController::getTetheredInterfaceList() const {
492*8542734aSAndroid Build Coastguard Worker return mInterfaces;
493*8542734aSAndroid Build Coastguard Worker }
494*8542734aSAndroid Build Coastguard Worker
setupIptablesHooks()495*8542734aSAndroid Build Coastguard Worker int TetherController::setupIptablesHooks() {
496*8542734aSAndroid Build Coastguard Worker int res;
497*8542734aSAndroid Build Coastguard Worker res = setDefaults();
498*8542734aSAndroid Build Coastguard Worker if (res < 0) {
499*8542734aSAndroid Build Coastguard Worker return res;
500*8542734aSAndroid Build Coastguard Worker }
501*8542734aSAndroid Build Coastguard Worker
502*8542734aSAndroid Build Coastguard Worker // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large
503*8542734aSAndroid Build Coastguard Worker // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA.
504*8542734aSAndroid Build Coastguard Worker // This is no longer optional and tethering will fail to start if it fails.
505*8542734aSAndroid Build Coastguard Worker std::string mssRewriteCommand = StringPrintf(
506*8542734aSAndroid Build Coastguard Worker "*mangle\n"
507*8542734aSAndroid Build Coastguard Worker "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n"
508*8542734aSAndroid Build Coastguard Worker "COMMIT\n", LOCAL_MANGLE_FORWARD);
509*8542734aSAndroid Build Coastguard Worker
510*8542734aSAndroid Build Coastguard Worker // This is for tethering counters. This chain is reached via --goto, and then RETURNS.
511*8542734aSAndroid Build Coastguard Worker std::string defaultCommands = StringPrintf(
512*8542734aSAndroid Build Coastguard Worker "*filter\n"
513*8542734aSAndroid Build Coastguard Worker ":%s -\n"
514*8542734aSAndroid Build Coastguard Worker "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN);
515*8542734aSAndroid Build Coastguard Worker
516*8542734aSAndroid Build Coastguard Worker res = iptablesRestoreFunction(V4, mssRewriteCommand, nullptr);
517*8542734aSAndroid Build Coastguard Worker if (res < 0) {
518*8542734aSAndroid Build Coastguard Worker return res;
519*8542734aSAndroid Build Coastguard Worker }
520*8542734aSAndroid Build Coastguard Worker
521*8542734aSAndroid Build Coastguard Worker res = iptablesRestoreFunction(V4V6, defaultCommands, nullptr);
522*8542734aSAndroid Build Coastguard Worker if (res < 0) {
523*8542734aSAndroid Build Coastguard Worker return res;
524*8542734aSAndroid Build Coastguard Worker }
525*8542734aSAndroid Build Coastguard Worker
526*8542734aSAndroid Build Coastguard Worker mFwdIfaces.clear();
527*8542734aSAndroid Build Coastguard Worker
528*8542734aSAndroid Build Coastguard Worker return 0;
529*8542734aSAndroid Build Coastguard Worker }
530*8542734aSAndroid Build Coastguard Worker
setDefaults()531*8542734aSAndroid Build Coastguard Worker int TetherController::setDefaults() {
532*8542734aSAndroid Build Coastguard Worker std::string v4Cmd = StringPrintf(
533*8542734aSAndroid Build Coastguard Worker "*filter\n"
534*8542734aSAndroid Build Coastguard Worker ":%s -\n"
535*8542734aSAndroid Build Coastguard Worker "-A %s -j DROP\n"
536*8542734aSAndroid Build Coastguard Worker "COMMIT\n"
537*8542734aSAndroid Build Coastguard Worker "*nat\n"
538*8542734aSAndroid Build Coastguard Worker ":%s -\n"
539*8542734aSAndroid Build Coastguard Worker "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING);
540*8542734aSAndroid Build Coastguard Worker
541*8542734aSAndroid Build Coastguard Worker std::string v6Cmd = StringPrintf(
542*8542734aSAndroid Build Coastguard Worker "*filter\n"
543*8542734aSAndroid Build Coastguard Worker ":%s -\n"
544*8542734aSAndroid Build Coastguard Worker "COMMIT\n"
545*8542734aSAndroid Build Coastguard Worker "*raw\n"
546*8542734aSAndroid Build Coastguard Worker ":%s -\n"
547*8542734aSAndroid Build Coastguard Worker "COMMIT\n",
548*8542734aSAndroid Build Coastguard Worker LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
549*8542734aSAndroid Build Coastguard Worker
550*8542734aSAndroid Build Coastguard Worker int res = iptablesRestoreFunction(V4, v4Cmd, nullptr);
551*8542734aSAndroid Build Coastguard Worker if (res < 0) {
552*8542734aSAndroid Build Coastguard Worker return res;
553*8542734aSAndroid Build Coastguard Worker }
554*8542734aSAndroid Build Coastguard Worker
555*8542734aSAndroid Build Coastguard Worker res = iptablesRestoreFunction(V6, v6Cmd, nullptr);
556*8542734aSAndroid Build Coastguard Worker if (res < 0) {
557*8542734aSAndroid Build Coastguard Worker return res;
558*8542734aSAndroid Build Coastguard Worker }
559*8542734aSAndroid Build Coastguard Worker
560*8542734aSAndroid Build Coastguard Worker return 0;
561*8542734aSAndroid Build Coastguard Worker }
562*8542734aSAndroid Build Coastguard Worker
enableNat(const char * intIface,const char * extIface)563*8542734aSAndroid Build Coastguard Worker int TetherController::enableNat(const char* intIface, const char* extIface) {
564*8542734aSAndroid Build Coastguard Worker ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
565*8542734aSAndroid Build Coastguard Worker
566*8542734aSAndroid Build Coastguard Worker if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
567*8542734aSAndroid Build Coastguard Worker return -ENODEV;
568*8542734aSAndroid Build Coastguard Worker }
569*8542734aSAndroid Build Coastguard Worker
570*8542734aSAndroid Build Coastguard Worker /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */
571*8542734aSAndroid Build Coastguard Worker if (!strcmp(intIface, extIface)) {
572*8542734aSAndroid Build Coastguard Worker ALOGE("Duplicate interface specified: %s %s", intIface, extIface);
573*8542734aSAndroid Build Coastguard Worker return -EINVAL;
574*8542734aSAndroid Build Coastguard Worker }
575*8542734aSAndroid Build Coastguard Worker
576*8542734aSAndroid Build Coastguard Worker if (isForwardingPairEnabled(intIface, extIface)) {
577*8542734aSAndroid Build Coastguard Worker return 0;
578*8542734aSAndroid Build Coastguard Worker }
579*8542734aSAndroid Build Coastguard Worker
580*8542734aSAndroid Build Coastguard Worker // add this if we are the first enabled nat for this upstream
581*8542734aSAndroid Build Coastguard Worker if (!isAnyForwardingEnabledOnUpstream(extIface)) {
582*8542734aSAndroid Build Coastguard Worker std::vector<std::string> v4Cmds = {
583*8542734aSAndroid Build Coastguard Worker "*nat",
584*8542734aSAndroid Build Coastguard Worker StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface),
585*8542734aSAndroid Build Coastguard Worker "COMMIT\n"
586*8542734aSAndroid Build Coastguard Worker };
587*8542734aSAndroid Build Coastguard Worker
588*8542734aSAndroid Build Coastguard Worker if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) || setupIPv6CountersChain() ||
589*8542734aSAndroid Build Coastguard Worker setTetherGlobalAlertRule()) {
590*8542734aSAndroid Build Coastguard Worker ALOGE("Error setting postroute rule: iface=%s", extIface);
591*8542734aSAndroid Build Coastguard Worker if (!isAnyForwardingPairEnabled()) {
592*8542734aSAndroid Build Coastguard Worker // unwind what's been done, but don't care about success - what more could we do?
593*8542734aSAndroid Build Coastguard Worker setDefaults();
594*8542734aSAndroid Build Coastguard Worker }
595*8542734aSAndroid Build Coastguard Worker return -EREMOTEIO;
596*8542734aSAndroid Build Coastguard Worker }
597*8542734aSAndroid Build Coastguard Worker }
598*8542734aSAndroid Build Coastguard Worker
599*8542734aSAndroid Build Coastguard Worker if (setForwardRules(true, intIface, extIface) != 0) {
600*8542734aSAndroid Build Coastguard Worker ALOGE("Error setting forward rules");
601*8542734aSAndroid Build Coastguard Worker if (!isAnyForwardingPairEnabled()) {
602*8542734aSAndroid Build Coastguard Worker setDefaults();
603*8542734aSAndroid Build Coastguard Worker }
604*8542734aSAndroid Build Coastguard Worker return -ENODEV;
605*8542734aSAndroid Build Coastguard Worker }
606*8542734aSAndroid Build Coastguard Worker
607*8542734aSAndroid Build Coastguard Worker return 0;
608*8542734aSAndroid Build Coastguard Worker }
609*8542734aSAndroid Build Coastguard Worker
setTetherGlobalAlertRule()610*8542734aSAndroid Build Coastguard Worker int TetherController::setTetherGlobalAlertRule() {
611*8542734aSAndroid Build Coastguard Worker // Only add this if we are the first enabled nat
612*8542734aSAndroid Build Coastguard Worker if (isAnyForwardingPairEnabled()) {
613*8542734aSAndroid Build Coastguard Worker return 0;
614*8542734aSAndroid Build Coastguard Worker }
615*8542734aSAndroid Build Coastguard Worker const std::string cmds =
616*8542734aSAndroid Build Coastguard Worker "*filter\n" +
617*8542734aSAndroid Build Coastguard Worker StringPrintf("-I %s -j %s\n", LOCAL_FORWARD, BandwidthController::LOCAL_GLOBAL_ALERT) +
618*8542734aSAndroid Build Coastguard Worker "COMMIT\n";
619*8542734aSAndroid Build Coastguard Worker
620*8542734aSAndroid Build Coastguard Worker return iptablesRestoreFunction(V4V6, cmds, nullptr);
621*8542734aSAndroid Build Coastguard Worker }
622*8542734aSAndroid Build Coastguard Worker
setupIPv6CountersChain()623*8542734aSAndroid Build Coastguard Worker int TetherController::setupIPv6CountersChain() {
624*8542734aSAndroid Build Coastguard Worker // Only add this if we are the first enabled nat
625*8542734aSAndroid Build Coastguard Worker if (isAnyForwardingPairEnabled()) {
626*8542734aSAndroid Build Coastguard Worker return 0;
627*8542734aSAndroid Build Coastguard Worker }
628*8542734aSAndroid Build Coastguard Worker
629*8542734aSAndroid Build Coastguard Worker /*
630*8542734aSAndroid Build Coastguard Worker * IPv6 tethering doesn't need the state-based conntrack rules, so
631*8542734aSAndroid Build Coastguard Worker * it unconditionally jumps to the tether counters chain all the time.
632*8542734aSAndroid Build Coastguard Worker */
633*8542734aSAndroid Build Coastguard Worker const std::string v6Cmds =
634*8542734aSAndroid Build Coastguard Worker "*filter\n" +
635*8542734aSAndroid Build Coastguard Worker StringPrintf("-A %s -g %s\n", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN) + "COMMIT\n";
636*8542734aSAndroid Build Coastguard Worker
637*8542734aSAndroid Build Coastguard Worker return iptablesRestoreFunction(V6, v6Cmds, nullptr);
638*8542734aSAndroid Build Coastguard Worker }
639*8542734aSAndroid Build Coastguard Worker
640*8542734aSAndroid Build Coastguard Worker // Gets a pointer to the ForwardingDownstream for an interface pair in the map, or nullptr
findForwardingDownstream(const std::string & intIface,const std::string & extIface)641*8542734aSAndroid Build Coastguard Worker TetherController::ForwardingDownstream* TetherController::findForwardingDownstream(
642*8542734aSAndroid Build Coastguard Worker const std::string& intIface, const std::string& extIface) {
643*8542734aSAndroid Build Coastguard Worker auto extIfaceMatches = mFwdIfaces.equal_range(extIface);
644*8542734aSAndroid Build Coastguard Worker for (auto it = extIfaceMatches.first; it != extIfaceMatches.second; ++it) {
645*8542734aSAndroid Build Coastguard Worker if (it->second.iface == intIface) {
646*8542734aSAndroid Build Coastguard Worker return &(it->second);
647*8542734aSAndroid Build Coastguard Worker }
648*8542734aSAndroid Build Coastguard Worker }
649*8542734aSAndroid Build Coastguard Worker return nullptr;
650*8542734aSAndroid Build Coastguard Worker }
651*8542734aSAndroid Build Coastguard Worker
addForwardingPair(const std::string & intIface,const std::string & extIface)652*8542734aSAndroid Build Coastguard Worker void TetherController::addForwardingPair(const std::string& intIface, const std::string& extIface) {
653*8542734aSAndroid Build Coastguard Worker ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface);
654*8542734aSAndroid Build Coastguard Worker if (existingEntry != nullptr) {
655*8542734aSAndroid Build Coastguard Worker existingEntry->active = true;
656*8542734aSAndroid Build Coastguard Worker return;
657*8542734aSAndroid Build Coastguard Worker }
658*8542734aSAndroid Build Coastguard Worker
659*8542734aSAndroid Build Coastguard Worker mFwdIfaces.insert(std::pair<std::string, ForwardingDownstream>(extIface, {
660*8542734aSAndroid Build Coastguard Worker .iface = intIface,
661*8542734aSAndroid Build Coastguard Worker .active = true
662*8542734aSAndroid Build Coastguard Worker }));
663*8542734aSAndroid Build Coastguard Worker }
664*8542734aSAndroid Build Coastguard Worker
markForwardingPairDisabled(const std::string & intIface,const std::string & extIface)665*8542734aSAndroid Build Coastguard Worker void TetherController::markForwardingPairDisabled(
666*8542734aSAndroid Build Coastguard Worker const std::string& intIface, const std::string& extIface) {
667*8542734aSAndroid Build Coastguard Worker ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface);
668*8542734aSAndroid Build Coastguard Worker if (existingEntry == nullptr) {
669*8542734aSAndroid Build Coastguard Worker return;
670*8542734aSAndroid Build Coastguard Worker }
671*8542734aSAndroid Build Coastguard Worker
672*8542734aSAndroid Build Coastguard Worker existingEntry->active = false;
673*8542734aSAndroid Build Coastguard Worker }
674*8542734aSAndroid Build Coastguard Worker
isForwardingPairEnabled(const std::string & intIface,const std::string & extIface)675*8542734aSAndroid Build Coastguard Worker bool TetherController::isForwardingPairEnabled(
676*8542734aSAndroid Build Coastguard Worker const std::string& intIface, const std::string& extIface) {
677*8542734aSAndroid Build Coastguard Worker ForwardingDownstream* existingEntry = findForwardingDownstream(intIface, extIface);
678*8542734aSAndroid Build Coastguard Worker return existingEntry != nullptr && existingEntry->active;
679*8542734aSAndroid Build Coastguard Worker }
680*8542734aSAndroid Build Coastguard Worker
isAnyForwardingEnabledOnUpstream(const std::string & extIface)681*8542734aSAndroid Build Coastguard Worker bool TetherController::isAnyForwardingEnabledOnUpstream(const std::string& extIface) {
682*8542734aSAndroid Build Coastguard Worker auto extIfaceMatches = mFwdIfaces.equal_range(extIface);
683*8542734aSAndroid Build Coastguard Worker for (auto it = extIfaceMatches.first; it != extIfaceMatches.second; ++it) {
684*8542734aSAndroid Build Coastguard Worker if (it->second.active) {
685*8542734aSAndroid Build Coastguard Worker return true;
686*8542734aSAndroid Build Coastguard Worker }
687*8542734aSAndroid Build Coastguard Worker }
688*8542734aSAndroid Build Coastguard Worker return false;
689*8542734aSAndroid Build Coastguard Worker }
690*8542734aSAndroid Build Coastguard Worker
isAnyForwardingPairEnabled()691*8542734aSAndroid Build Coastguard Worker bool TetherController::isAnyForwardingPairEnabled() {
692*8542734aSAndroid Build Coastguard Worker for (auto& it : mFwdIfaces) {
693*8542734aSAndroid Build Coastguard Worker if (it.second.active) {
694*8542734aSAndroid Build Coastguard Worker return true;
695*8542734aSAndroid Build Coastguard Worker }
696*8542734aSAndroid Build Coastguard Worker }
697*8542734aSAndroid Build Coastguard Worker return false;
698*8542734aSAndroid Build Coastguard Worker }
699*8542734aSAndroid Build Coastguard Worker
tetherCountingRuleExists(const std::string & iface1,const std::string & iface2)700*8542734aSAndroid Build Coastguard Worker bool TetherController::tetherCountingRuleExists(
701*8542734aSAndroid Build Coastguard Worker const std::string& iface1, const std::string& iface2) {
702*8542734aSAndroid Build Coastguard Worker // A counting rule exists if NAT was ever enabled for this interface pair, so if the pair
703*8542734aSAndroid Build Coastguard Worker // is in the map regardless of its active status. Rules are added both ways so we check with
704*8542734aSAndroid Build Coastguard Worker // the 2 combinations.
705*8542734aSAndroid Build Coastguard Worker return findForwardingDownstream(iface1, iface2) != nullptr
706*8542734aSAndroid Build Coastguard Worker || findForwardingDownstream(iface2, iface1) != nullptr;
707*8542734aSAndroid Build Coastguard Worker }
708*8542734aSAndroid Build Coastguard Worker
709*8542734aSAndroid Build Coastguard Worker /* static */
makeTetherCountingRule(const char * if1,const char * if2)710*8542734aSAndroid Build Coastguard Worker std::string TetherController::makeTetherCountingRule(const char *if1, const char *if2) {
711*8542734aSAndroid Build Coastguard Worker return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2);
712*8542734aSAndroid Build Coastguard Worker }
713*8542734aSAndroid Build Coastguard Worker
setForwardRules(bool add,const char * intIface,const char * extIface)714*8542734aSAndroid Build Coastguard Worker int TetherController::setForwardRules(bool add, const char *intIface, const char *extIface) {
715*8542734aSAndroid Build Coastguard Worker const char *op = add ? "-A" : "-D";
716*8542734aSAndroid Build Coastguard Worker
717*8542734aSAndroid Build Coastguard Worker std::string rpfilterCmd = StringPrintf(
718*8542734aSAndroid Build Coastguard Worker "*raw\n"
719*8542734aSAndroid Build Coastguard Worker "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
720*8542734aSAndroid Build Coastguard Worker "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface);
721*8542734aSAndroid Build Coastguard Worker if (iptablesRestoreFunction(V6, rpfilterCmd, nullptr) == -1 && add) {
722*8542734aSAndroid Build Coastguard Worker return -EREMOTEIO;
723*8542734aSAndroid Build Coastguard Worker }
724*8542734aSAndroid Build Coastguard Worker
725*8542734aSAndroid Build Coastguard Worker std::vector<std::string> v4 = {
726*8542734aSAndroid Build Coastguard Worker "*raw",
727*8542734aSAndroid Build Coastguard Worker StringPrintf("%s %s -p tcp --dport 21 -i %s -j CT --helper ftp", op,
728*8542734aSAndroid Build Coastguard Worker LOCAL_RAW_PREROUTING, intIface),
729*8542734aSAndroid Build Coastguard Worker StringPrintf("%s %s -p tcp --dport 1723 -i %s -j CT --helper pptp", op,
730*8542734aSAndroid Build Coastguard Worker LOCAL_RAW_PREROUTING, intIface),
731*8542734aSAndroid Build Coastguard Worker "COMMIT",
732*8542734aSAndroid Build Coastguard Worker "*filter",
733*8542734aSAndroid Build Coastguard Worker StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s", op,
734*8542734aSAndroid Build Coastguard Worker LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN),
735*8542734aSAndroid Build Coastguard Worker StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP", op, LOCAL_FORWARD,
736*8542734aSAndroid Build Coastguard Worker intIface, extIface),
737*8542734aSAndroid Build Coastguard Worker StringPrintf("%s %s -i %s -o %s -g %s", op, LOCAL_FORWARD, intIface, extIface,
738*8542734aSAndroid Build Coastguard Worker LOCAL_TETHER_COUNTERS_CHAIN),
739*8542734aSAndroid Build Coastguard Worker };
740*8542734aSAndroid Build Coastguard Worker
741*8542734aSAndroid Build Coastguard Worker std::vector<std::string> v6 = {
742*8542734aSAndroid Build Coastguard Worker "*filter",
743*8542734aSAndroid Build Coastguard Worker };
744*8542734aSAndroid Build Coastguard Worker
745*8542734aSAndroid Build Coastguard Worker // We only ever add tethering quota rules so that they stick.
746*8542734aSAndroid Build Coastguard Worker if (add && !tetherCountingRuleExists(intIface, extIface)) {
747*8542734aSAndroid Build Coastguard Worker v4.push_back(makeTetherCountingRule(intIface, extIface));
748*8542734aSAndroid Build Coastguard Worker v4.push_back(makeTetherCountingRule(extIface, intIface));
749*8542734aSAndroid Build Coastguard Worker v6.push_back(makeTetherCountingRule(intIface, extIface));
750*8542734aSAndroid Build Coastguard Worker v6.push_back(makeTetherCountingRule(extIface, intIface));
751*8542734aSAndroid Build Coastguard Worker }
752*8542734aSAndroid Build Coastguard Worker
753*8542734aSAndroid Build Coastguard Worker // Always make sure the drop rule is at the end.
754*8542734aSAndroid Build Coastguard Worker // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch
755*8542734aSAndroid Build Coastguard Worker // every time, starting with ":tetherctrl_FORWARD -\n". This would likely be a bit simpler.
756*8542734aSAndroid Build Coastguard Worker if (add) {
757*8542734aSAndroid Build Coastguard Worker v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD));
758*8542734aSAndroid Build Coastguard Worker v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD));
759*8542734aSAndroid Build Coastguard Worker }
760*8542734aSAndroid Build Coastguard Worker
761*8542734aSAndroid Build Coastguard Worker v4.push_back("COMMIT\n");
762*8542734aSAndroid Build Coastguard Worker v6.push_back("COMMIT\n");
763*8542734aSAndroid Build Coastguard Worker
764*8542734aSAndroid Build Coastguard Worker // We only add IPv6 rules here, never remove them.
765*8542734aSAndroid Build Coastguard Worker if (iptablesRestoreFunction(V4, Join(v4, '\n'), nullptr) == -1 ||
766*8542734aSAndroid Build Coastguard Worker (add && iptablesRestoreFunction(V6, Join(v6, '\n'), nullptr) == -1)) {
767*8542734aSAndroid Build Coastguard Worker // unwind what's been done, but don't care about success - what more could we do?
768*8542734aSAndroid Build Coastguard Worker if (add) {
769*8542734aSAndroid Build Coastguard Worker setForwardRules(false, intIface, extIface);
770*8542734aSAndroid Build Coastguard Worker }
771*8542734aSAndroid Build Coastguard Worker return -EREMOTEIO;
772*8542734aSAndroid Build Coastguard Worker }
773*8542734aSAndroid Build Coastguard Worker
774*8542734aSAndroid Build Coastguard Worker if (add) {
775*8542734aSAndroid Build Coastguard Worker addForwardingPair(intIface, extIface);
776*8542734aSAndroid Build Coastguard Worker } else {
777*8542734aSAndroid Build Coastguard Worker markForwardingPairDisabled(intIface, extIface);
778*8542734aSAndroid Build Coastguard Worker }
779*8542734aSAndroid Build Coastguard Worker
780*8542734aSAndroid Build Coastguard Worker return 0;
781*8542734aSAndroid Build Coastguard Worker }
782*8542734aSAndroid Build Coastguard Worker
disableNat(const char * intIface,const char * extIface)783*8542734aSAndroid Build Coastguard Worker int TetherController::disableNat(const char* intIface, const char* extIface) {
784*8542734aSAndroid Build Coastguard Worker if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
785*8542734aSAndroid Build Coastguard Worker errno = ENODEV;
786*8542734aSAndroid Build Coastguard Worker return -errno;
787*8542734aSAndroid Build Coastguard Worker }
788*8542734aSAndroid Build Coastguard Worker
789*8542734aSAndroid Build Coastguard Worker setForwardRules(false, intIface, extIface);
790*8542734aSAndroid Build Coastguard Worker if (!isAnyForwardingPairEnabled()) setDefaults();
791*8542734aSAndroid Build Coastguard Worker return 0;
792*8542734aSAndroid Build Coastguard Worker }
793*8542734aSAndroid Build Coastguard Worker
addStats(TetherStatsList & statsList,const TetherStats & stats)794*8542734aSAndroid Build Coastguard Worker void TetherController::addStats(TetherStatsList& statsList, const TetherStats& stats) {
795*8542734aSAndroid Build Coastguard Worker for (TetherStats& existing : statsList) {
796*8542734aSAndroid Build Coastguard Worker if (existing.addStatsIfMatch(stats)) {
797*8542734aSAndroid Build Coastguard Worker return;
798*8542734aSAndroid Build Coastguard Worker }
799*8542734aSAndroid Build Coastguard Worker }
800*8542734aSAndroid Build Coastguard Worker // No match. Insert a new interface pair.
801*8542734aSAndroid Build Coastguard Worker statsList.push_back(stats);
802*8542734aSAndroid Build Coastguard Worker }
803*8542734aSAndroid Build Coastguard Worker
804*8542734aSAndroid Build Coastguard Worker /*
805*8542734aSAndroid Build Coastguard Worker * Parse the ptks and bytes out of:
806*8542734aSAndroid Build Coastguard Worker * Chain tetherctrl_counters (4 references)
807*8542734aSAndroid Build Coastguard Worker * pkts bytes target prot opt in out source destination
808*8542734aSAndroid Build Coastguard Worker * 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
809*8542734aSAndroid Build Coastguard Worker * 27 2002 RETURN all -- rmnet0 wlan0 0.0.0.0/0 0.0.0.0/0
810*8542734aSAndroid Build Coastguard Worker * 1040 107471 RETURN all -- bt-pan rmnet0 0.0.0.0/0 0.0.0.0/0
811*8542734aSAndroid Build Coastguard Worker * 1450 1708806 RETURN all -- rmnet0 bt-pan 0.0.0.0/0 0.0.0.0/0
812*8542734aSAndroid Build Coastguard Worker * or:
813*8542734aSAndroid Build Coastguard Worker * Chain tetherctrl_counters (0 references)
814*8542734aSAndroid Build Coastguard Worker * pkts bytes target prot opt in out source destination
815*8542734aSAndroid Build Coastguard Worker * 0 0 RETURN all -- wlan0 rmnet_data0 ::/0 ::/0
816*8542734aSAndroid Build Coastguard Worker * 0 0 RETURN all -- rmnet_data0 wlan0 ::/0 ::/0
817*8542734aSAndroid Build Coastguard Worker *
818*8542734aSAndroid Build Coastguard Worker */
addForwardChainStats(TetherStatsList & statsList,const std::string & statsOutput,std::string & extraProcessingInfo)819*8542734aSAndroid Build Coastguard Worker int TetherController::addForwardChainStats(TetherStatsList& statsList,
820*8542734aSAndroid Build Coastguard Worker const std::string& statsOutput,
821*8542734aSAndroid Build Coastguard Worker std::string &extraProcessingInfo) {
822*8542734aSAndroid Build Coastguard Worker enum IndexOfIptChain {
823*8542734aSAndroid Build Coastguard Worker ORIG_LINE,
824*8542734aSAndroid Build Coastguard Worker PACKET_COUNTS,
825*8542734aSAndroid Build Coastguard Worker BYTE_COUNTS,
826*8542734aSAndroid Build Coastguard Worker IFACE0_NAME,
827*8542734aSAndroid Build Coastguard Worker IFACE1_NAME,
828*8542734aSAndroid Build Coastguard Worker SOURCE,
829*8542734aSAndroid Build Coastguard Worker DESTINATION
830*8542734aSAndroid Build Coastguard Worker };
831*8542734aSAndroid Build Coastguard Worker TetherStats stats;
832*8542734aSAndroid Build Coastguard Worker const TetherStats empty;
833*8542734aSAndroid Build Coastguard Worker
834*8542734aSAndroid Build Coastguard Worker static const std::string NUM = "(\\d+)";
835*8542734aSAndroid Build Coastguard Worker static const std::string IFACE = "([^\\s]+)";
836*8542734aSAndroid Build Coastguard Worker static const std::string DST = "(0.0.0.0/0|::/0)";
837*8542734aSAndroid Build Coastguard Worker static const std::string COUNTERS = "\\s*" + NUM + "\\s+" + NUM +
838*8542734aSAndroid Build Coastguard Worker " RETURN all -- " + IFACE + "\\s+" + IFACE +
839*8542734aSAndroid Build Coastguard Worker "\\s+" + DST + "\\s+" + DST;
840*8542734aSAndroid Build Coastguard Worker static const std::regex IP_RE(COUNTERS);
841*8542734aSAndroid Build Coastguard Worker
842*8542734aSAndroid Build Coastguard Worker const std::vector<std::string> lines = base::Split(statsOutput, "\n");
843*8542734aSAndroid Build Coastguard Worker int headerLine = 0;
844*8542734aSAndroid Build Coastguard Worker for (const std::string& line : lines) {
845*8542734aSAndroid Build Coastguard Worker // Skip headers.
846*8542734aSAndroid Build Coastguard Worker if (headerLine < 2) {
847*8542734aSAndroid Build Coastguard Worker if (line.empty()) {
848*8542734aSAndroid Build Coastguard Worker ALOGV("Empty header while parsing tethering stats");
849*8542734aSAndroid Build Coastguard Worker return -EREMOTEIO;
850*8542734aSAndroid Build Coastguard Worker }
851*8542734aSAndroid Build Coastguard Worker headerLine++;
852*8542734aSAndroid Build Coastguard Worker continue;
853*8542734aSAndroid Build Coastguard Worker }
854*8542734aSAndroid Build Coastguard Worker
855*8542734aSAndroid Build Coastguard Worker if (line.empty()) continue;
856*8542734aSAndroid Build Coastguard Worker
857*8542734aSAndroid Build Coastguard Worker extraProcessingInfo = line;
858*8542734aSAndroid Build Coastguard Worker std::smatch matches;
859*8542734aSAndroid Build Coastguard Worker if (!std::regex_search(line, matches, IP_RE)) return -EREMOTEIO;
860*8542734aSAndroid Build Coastguard Worker // 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
861*8542734aSAndroid Build Coastguard Worker // 26 2373 RETURN all -- wlan0 rmnet0 ::/0 ::/0
862*8542734aSAndroid Build Coastguard Worker // TODO: Replace strtoXX() calls with ParseUint() /ParseInt()
863*8542734aSAndroid Build Coastguard Worker int64_t packets = strtoul(matches[PACKET_COUNTS].str().c_str(), nullptr, 10);
864*8542734aSAndroid Build Coastguard Worker int64_t bytes = strtoul(matches[BYTE_COUNTS].str().c_str(), nullptr, 10);
865*8542734aSAndroid Build Coastguard Worker std::string iface0 = matches[IFACE0_NAME].str();
866*8542734aSAndroid Build Coastguard Worker std::string iface1 = matches[IFACE1_NAME].str();
867*8542734aSAndroid Build Coastguard Worker std::string rest = matches[SOURCE].str();
868*8542734aSAndroid Build Coastguard Worker
869*8542734aSAndroid Build Coastguard Worker ALOGV("parse iface0=<%s> iface1=<%s> pkts=%" PRId64 " bytes=%" PRId64
870*8542734aSAndroid Build Coastguard Worker " rest=<%s> orig line=<%s>",
871*8542734aSAndroid Build Coastguard Worker iface0.c_str(), iface1.c_str(), packets, bytes, rest.c_str(), line.c_str());
872*8542734aSAndroid Build Coastguard Worker /*
873*8542734aSAndroid Build Coastguard Worker * The following assumes that the 1st rule has in:extIface out:intIface,
874*8542734aSAndroid Build Coastguard Worker * which is what TetherController sets up.
875*8542734aSAndroid Build Coastguard Worker * The 1st matches rx, and sets up the pair for the tx side.
876*8542734aSAndroid Build Coastguard Worker */
877*8542734aSAndroid Build Coastguard Worker if (stats.intIface.empty()) {
878*8542734aSAndroid Build Coastguard Worker ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64 " rx_packets=%" PRId64
879*8542734aSAndroid Build Coastguard Worker " ", iface0.c_str(), iface1.c_str(), bytes, packets);
880*8542734aSAndroid Build Coastguard Worker stats.intIface = iface0;
881*8542734aSAndroid Build Coastguard Worker stats.extIface = iface1;
882*8542734aSAndroid Build Coastguard Worker stats.txPackets = packets;
883*8542734aSAndroid Build Coastguard Worker stats.txBytes = bytes;
884*8542734aSAndroid Build Coastguard Worker } else if (stats.intIface == iface1 && stats.extIface == iface0) {
885*8542734aSAndroid Build Coastguard Worker ALOGV("0Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64 " rx_packets=%" PRId64
886*8542734aSAndroid Build Coastguard Worker " ", iface0.c_str(), iface1.c_str(), bytes, packets);
887*8542734aSAndroid Build Coastguard Worker stats.rxPackets = packets;
888*8542734aSAndroid Build Coastguard Worker stats.rxBytes = bytes;
889*8542734aSAndroid Build Coastguard Worker }
890*8542734aSAndroid Build Coastguard Worker if (stats.rxBytes != -1 && stats.txBytes != -1) {
891*8542734aSAndroid Build Coastguard Worker ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64, stats.rxBytes, stats.txBytes);
892*8542734aSAndroid Build Coastguard Worker addStats(statsList, stats);
893*8542734aSAndroid Build Coastguard Worker stats = empty;
894*8542734aSAndroid Build Coastguard Worker }
895*8542734aSAndroid Build Coastguard Worker }
896*8542734aSAndroid Build Coastguard Worker
897*8542734aSAndroid Build Coastguard Worker /* It is always an error to find only one side of the stats. */
898*8542734aSAndroid Build Coastguard Worker if (((stats.rxBytes == -1) != (stats.txBytes == -1))) {
899*8542734aSAndroid Build Coastguard Worker return -EREMOTEIO;
900*8542734aSAndroid Build Coastguard Worker }
901*8542734aSAndroid Build Coastguard Worker return 0;
902*8542734aSAndroid Build Coastguard Worker }
903*8542734aSAndroid Build Coastguard Worker
getTetherStats()904*8542734aSAndroid Build Coastguard Worker StatusOr<TetherController::TetherStatsList> TetherController::getTetherStats() {
905*8542734aSAndroid Build Coastguard Worker TetherStatsList statsList;
906*8542734aSAndroid Build Coastguard Worker std::string parsedIptablesOutput;
907*8542734aSAndroid Build Coastguard Worker
908*8542734aSAndroid Build Coastguard Worker for (const IptablesTarget target : {V4, V6}) {
909*8542734aSAndroid Build Coastguard Worker std::string statsString;
910*8542734aSAndroid Build Coastguard Worker if (int ret = iptablesRestoreFunction(target, GET_TETHER_STATS_COMMAND, &statsString)) {
911*8542734aSAndroid Build Coastguard Worker return statusFromErrno(-ret, StringPrintf("failed to fetch tether stats (%d): %d",
912*8542734aSAndroid Build Coastguard Worker target, ret));
913*8542734aSAndroid Build Coastguard Worker }
914*8542734aSAndroid Build Coastguard Worker
915*8542734aSAndroid Build Coastguard Worker if (int ret = addForwardChainStats(statsList, statsString, parsedIptablesOutput)) {
916*8542734aSAndroid Build Coastguard Worker return statusFromErrno(-ret, StringPrintf("failed to parse %s tether stats:\n%s",
917*8542734aSAndroid Build Coastguard Worker target == V4 ? "IPv4": "IPv6",
918*8542734aSAndroid Build Coastguard Worker parsedIptablesOutput.c_str()));
919*8542734aSAndroid Build Coastguard Worker }
920*8542734aSAndroid Build Coastguard Worker }
921*8542734aSAndroid Build Coastguard Worker
922*8542734aSAndroid Build Coastguard Worker return statsList;
923*8542734aSAndroid Build Coastguard Worker }
924*8542734aSAndroid Build Coastguard Worker
dumpIfaces(DumpWriter & dw)925*8542734aSAndroid Build Coastguard Worker void TetherController::dumpIfaces(DumpWriter& dw) {
926*8542734aSAndroid Build Coastguard Worker dw.println("Interface pairs:");
927*8542734aSAndroid Build Coastguard Worker
928*8542734aSAndroid Build Coastguard Worker ScopedIndent ifaceIndent(dw);
929*8542734aSAndroid Build Coastguard Worker for (const auto& it : mFwdIfaces) {
930*8542734aSAndroid Build Coastguard Worker dw.println("%s -> %s %s", it.first.c_str(), it.second.iface.c_str(),
931*8542734aSAndroid Build Coastguard Worker (it.second.active ? "ACTIVE" : "DISABLED"));
932*8542734aSAndroid Build Coastguard Worker }
933*8542734aSAndroid Build Coastguard Worker }
934*8542734aSAndroid Build Coastguard Worker
dump(DumpWriter & dw)935*8542734aSAndroid Build Coastguard Worker void TetherController::dump(DumpWriter& dw) {
936*8542734aSAndroid Build Coastguard Worker std::lock_guard guard(lock);
937*8542734aSAndroid Build Coastguard Worker
938*8542734aSAndroid Build Coastguard Worker ScopedIndent tetherControllerIndent(dw);
939*8542734aSAndroid Build Coastguard Worker dw.println("TetherController");
940*8542734aSAndroid Build Coastguard Worker dw.incIndent();
941*8542734aSAndroid Build Coastguard Worker
942*8542734aSAndroid Build Coastguard Worker dw.println("Forwarding requests: " + Join(mForwardingRequests, ' '));
943*8542734aSAndroid Build Coastguard Worker if (mDnsNetId != 0) {
944*8542734aSAndroid Build Coastguard Worker dw.println(StringPrintf("DNS: netId %d servers [%s]", mDnsNetId,
945*8542734aSAndroid Build Coastguard Worker Join(mDnsForwarders, ", ").c_str()));
946*8542734aSAndroid Build Coastguard Worker }
947*8542734aSAndroid Build Coastguard Worker if (mDaemonPid != 0) {
948*8542734aSAndroid Build Coastguard Worker dw.println("dnsmasq PID: %d", mDaemonPid);
949*8542734aSAndroid Build Coastguard Worker }
950*8542734aSAndroid Build Coastguard Worker
951*8542734aSAndroid Build Coastguard Worker dumpIfaces(dw);
952*8542734aSAndroid Build Coastguard Worker }
953*8542734aSAndroid Build Coastguard Worker
954*8542734aSAndroid Build Coastguard Worker } // namespace net
955*8542734aSAndroid Build Coastguard Worker } // namespace android
956