blob: a60024ea8d3d3cc4c103800824a8a3cac9ad17d8 [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>
Lorenzo Colittia93126d2017-08-24 13:28:19 +090021#include <stdlib.h>
Olivier Baillyff2c0d82010-11-17 11:45:07 -080022#include <string.h>
San Mehat18737842010-01-21 09:22:43 -080023
San Mehat9d10b342010-01-18 09:51:02 -080024#include <sys/socket.h>
25#include <sys/stat.h>
San Mehat18737842010-01-21 09:22:43 -080026#include <sys/types.h>
27#include <sys/wait.h>
28
San Mehat9d10b342010-01-18 09:51:02 -080029#include <netinet/in.h>
30#include <arpa/inet.h>
31
32#define LOG_TAG "TetherController"
Lorenzo Colittia93126d2017-08-24 13:28:19 +090033#include <android-base/strings.h>
34#include <android-base/stringprintf.h>
San Mehat9d10b342010-01-18 09:51:02 -080035#include <cutils/log.h>
Kazuhiro Ondo6b858eb2011-06-24 20:31:03 -050036#include <cutils/properties.h>
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +090037#include <netdutils/StatusOr.h>
San Mehat9d10b342010-01-18 09:51:02 -080038
Lorenzo Colitti667c4772014-08-26 14:13:07 -070039#include "Fwmark.h"
JP Abgrall69261cb2014-06-19 18:35:24 -070040#include "NetdConstants.h"
Lorenzo Colitti667c4772014-08-26 14:13:07 -070041#include "Permission.h"
Erik Kline1d065ba2016-06-08 13:24:45 +090042#include "InterfaceController.h"
Lorenzo Colittie20a5262017-05-09 18:30:44 +090043#include "NetworkController.h"
Lorenzo Colittia93126d2017-08-24 13:28:19 +090044#include "ResponseCode.h"
San Mehat9d10b342010-01-18 09:51:02 -080045#include "TetherController.h"
46
Lorenzo Colittia93126d2017-08-24 13:28:19 +090047using android::base::Join;
48using android::base::StringPrintf;
49using android::base::StringAppendF;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +090050using android::netdutils::StatusOr;
51using android::netdutils::statusFromErrno;
Lorenzo Colittia93126d2017-08-24 13:28:19 +090052
Lorenzo Colitti799625c2015-02-25 12:52:00 +090053namespace {
54
Erik Kline1d065ba2016-06-08 13:24:45 +090055const char BP_TOOLS_MODE[] = "bp-tools";
56const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
57const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
58const char SEPARATOR[] = "|";
Erik Kline93f9b222017-10-22 21:24:58 +090059constexpr const char kTcpBeLiberal[] = "/proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal";
Lorenzo Colitti799625c2015-02-25 12:52:00 +090060
61bool writeToFile(const char* filename, const char* value) {
Nick Kralevichb95c60c2016-11-19 09:09:16 -080062 int fd = open(filename, O_WRONLY | O_CLOEXEC);
Nicolas Geoffrayafd40372015-03-16 11:58:06 +000063 if (fd < 0) {
64 ALOGE("Failed to open %s: %s", filename, strerror(errno));
65 return false;
66 }
67
68 const ssize_t len = strlen(value);
69 if (write(fd, value, len) != len) {
70 ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
71 close(fd);
72 return false;
73 }
74 close(fd);
75 return true;
Lorenzo Colitti799625c2015-02-25 12:52:00 +090076}
77
Erik Kline93f9b222017-10-22 21:24:58 +090078// TODO: Consider altering TCP and UDP timeouts as well.
79void configureForTethering(bool enabled) {
80 writeToFile(kTcpBeLiberal, enabled ? "1" : "0");
81}
82
Erik Kline1d065ba2016-06-08 13:24:45 +090083bool configureForIPv6Router(const char *interface) {
84 return (InterfaceController::setEnableIPv6(interface, 0) == 0)
85 && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
Erik Kline6cddf512016-08-09 15:28:42 +090086 && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0)
87 && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0)
Erik Kline1d065ba2016-06-08 13:24:45 +090088 && (InterfaceController::setEnableIPv6(interface, 1) == 0);
89}
90
91void configureForIPv6Client(const char *interface) {
92 InterfaceController::setAcceptIPv6Ra(interface, 1);
Erik Kline6cddf512016-08-09 15:28:42 +090093 InterfaceController::setAcceptIPv6Dad(interface, 1);
94 InterfaceController::setIPv6DadTransmits(interface, "1");
Erik Kline1d065ba2016-06-08 13:24:45 +090095 InterfaceController::setEnableIPv6(interface, 0);
96}
97
Lorenzo Colitti799625c2015-02-25 12:52:00 +090098bool inBpToolsMode() {
99 // In BP tools mode, do not disable IP forwarding
100 char bootmode[PROPERTY_VALUE_MAX] = {0};
101 property_get("ro.bootmode", bootmode, "unknown");
102 return !strcmp(BP_TOOLS_MODE, bootmode);
103}
104
105} // namespace
106
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900107namespace android {
108namespace net {
109
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900110auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
111
112const int MAX_IPT_OUTPUT_LINE_LEN = 256;
113
114const std::string GET_TETHER_STATS_COMMAND = StringPrintf(
115 "*filter\n"
116 "-nvx -L %s\n"
117 "COMMIT\n", android::net::TetherController::LOCAL_TETHER_COUNTERS_CHAIN);
118
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700119TetherController::TetherController() {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700120 mDnsNetId = 0;
San Mehat9d10b342010-01-18 09:51:02 -0800121 mDaemonFd = -1;
122 mDaemonPid = 0;
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900123 if (inBpToolsMode()) {
124 enableForwarding(BP_TOOLS_MODE);
125 } else {
126 setIpFwdEnabled();
127 }
San Mehat9d10b342010-01-18 09:51:02 -0800128}
129
130TetherController::~TetherController() {
Erik Kline1d065ba2016-06-08 13:24:45 +0900131 mInterfaces.clear();
132 mDnsForwarders.clear();
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900133 mForwardingRequests.clear();
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900134 ifacePairList.clear();
San Mehat9d10b342010-01-18 09:51:02 -0800135}
136
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900137bool TetherController::setIpFwdEnabled() {
138 bool success = true;
139 const char* value = mForwardingRequests.empty() ? "0" : "1";
140 ALOGD("Setting IP forward enable = %s", value);
141 success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
142 success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
143 return success;
San Mehat9d10b342010-01-18 09:51:02 -0800144}
145
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900146bool TetherController::enableForwarding(const char* requester) {
147 // Don't return an error if this requester already requested forwarding. Only return errors for
148 // things that the caller caller needs to care about, such as "couldn't write to the file to
149 // enable forwarding".
150 mForwardingRequests.insert(requester);
151 return setIpFwdEnabled();
152}
San Mehat9d10b342010-01-18 09:51:02 -0800153
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900154bool TetherController::disableForwarding(const char* requester) {
155 mForwardingRequests.erase(requester);
156 return setIpFwdEnabled();
157}
San Mehat9d10b342010-01-18 09:51:02 -0800158
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900159size_t TetherController::forwardingRequestCount() {
160 return mForwardingRequests.size();
San Mehat9d10b342010-01-18 09:51:02 -0800161}
162
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900163#define TETHER_START_CONST_ARG 10
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800164
Erik Kline13fa01f2015-11-12 17:49:23 +0900165int TetherController::startTethering(int num_addrs, char **dhcp_ranges) {
San Mehat9d10b342010-01-18 09:51:02 -0800166 if (mDaemonPid != 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000167 ALOGE("Tethering already started");
San Mehat9d10b342010-01-18 09:51:02 -0800168 errno = EBUSY;
169 return -1;
170 }
171
Steve Block7b984e32011-12-20 16:22:42 +0000172 ALOGD("Starting tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800173
174 pid_t pid;
175 int pipefd[2];
176
177 if (pipe(pipefd) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000178 ALOGE("pipe failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800179 return -1;
180 }
181
182 /*
183 * TODO: Create a monitoring thread to handle and restart
184 * the daemon if it exits prematurely
185 */
186 if ((pid = fork()) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000187 ALOGE("fork failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800188 close(pipefd[0]);
189 close(pipefd[1]);
190 return -1;
191 }
192
193 if (!pid) {
194 close(pipefd[1]);
195 if (pipefd[0] != STDIN_FILENO) {
196 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
Steve Block5ea0c052012-01-06 19:18:11 +0000197 ALOGE("dup2 failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800198 return -1;
199 }
200 close(pipefd[0]);
201 }
San Mehat9d10b342010-01-18 09:51:02 -0800202
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900203 Fwmark fwmark;
204 fwmark.netId = NetworkController::LOCAL_NET_ID;
205 fwmark.explicitlySelected = true;
206 fwmark.protectedFromVpn = true;
207 fwmark.permission = PERMISSION_SYSTEM;
208 char markStr[UINT32_HEX_STRLEN];
209 snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue);
210
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800211 int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1;
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700212 char **args = (char **)malloc(sizeof(char *) * num_processed_args);
213 args[num_processed_args - 1] = NULL;
214 args[0] = (char *)"/system/bin/dnsmasq";
Peter Nilssonb756f692011-09-08 09:48:31 -0700215 args[1] = (char *)"--keep-in-foreground";
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700216 args[2] = (char *)"--no-resolv";
217 args[3] = (char *)"--no-poll";
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800218 args[4] = (char *)"--dhcp-authoritative";
Jeff Sharkey6df79da2012-04-18 21:53:35 -0700219 // TODO: pipe through metered status from ConnService
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800220 args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
221 args[6] = (char *)"--pid-file";
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900222 args[7] = (char *)"--listen-mark";
223 args[8] = (char *)markStr;
224 args[9] = (char *)"";
San Mehat9d10b342010-01-18 09:51:02 -0800225
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800226 int nextArg = TETHER_START_CONST_ARG;
Erik Kline13fa01f2015-11-12 17:49:23 +0900227 for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
228 asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h",
229 dhcp_ranges[addrIndex], dhcp_ranges[addrIndex+1]);
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700230 }
231
232 if (execv(args[0], args)) {
Steve Block5ea0c052012-01-06 19:18:11 +0000233 ALOGE("execl failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800234 }
Steve Block5ea0c052012-01-06 19:18:11 +0000235 ALOGE("Should never get here!");
JP Abgrallce4f3792012-08-06 13:44:44 -0700236 _exit(-1);
San Mehat9d10b342010-01-18 09:51:02 -0800237 } else {
238 close(pipefd[0]);
239 mDaemonPid = pid;
240 mDaemonFd = pipefd[1];
Erik Kline93f9b222017-10-22 21:24:58 +0900241 configureForTethering(true);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800242 applyDnsInterfaces();
Steve Block7b984e32011-12-20 16:22:42 +0000243 ALOGD("Tethering services running");
San Mehat9d10b342010-01-18 09:51:02 -0800244 }
245
246 return 0;
247}
248
249int TetherController::stopTethering() {
Erik Kline93f9b222017-10-22 21:24:58 +0900250 configureForTethering(false);
San Mehat9d10b342010-01-18 09:51:02 -0800251
252 if (mDaemonPid == 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000253 ALOGE("Tethering already stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800254 return 0;
255 }
256
Steve Block7b984e32011-12-20 16:22:42 +0000257 ALOGD("Stopping tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800258
259 kill(mDaemonPid, SIGTERM);
San Mehat18737842010-01-21 09:22:43 -0800260 waitpid(mDaemonPid, NULL, 0);
San Mehat9d10b342010-01-18 09:51:02 -0800261 mDaemonPid = 0;
262 close(mDaemonFd);
263 mDaemonFd = -1;
Steve Block7b984e32011-12-20 16:22:42 +0000264 ALOGD("Tethering services stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800265 return 0;
266}
Matthew Xie19944102012-07-12 16:42:07 -0700267
San Mehat9d10b342010-01-18 09:51:02 -0800268bool TetherController::isTetheringStarted() {
269 return (mDaemonPid == 0 ? false : true);
270}
271
Kenny Rootcf52faf2010-02-18 09:59:55 -0800272#define MAX_CMD_SIZE 1024
273
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700274int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
San Mehat9d10b342010-01-18 09:51:02 -0800275 int i;
Kenny Rootcf52faf2010-02-18 09:59:55 -0800276 char daemonCmd[MAX_CMD_SIZE];
San Mehat9d10b342010-01-18 09:51:02 -0800277
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700278 Fwmark fwmark;
279 fwmark.netId = netId;
280 fwmark.explicitlySelected = true;
281 fwmark.protectedFromVpn = true;
282 fwmark.permission = PERMISSION_SYSTEM;
283
Erik Kline13fa01f2015-11-12 17:49:23 +0900284 snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue);
Kenny Rootcf52faf2010-02-18 09:59:55 -0800285 int cmdLen = strlen(daemonCmd);
San Mehat9d10b342010-01-18 09:51:02 -0800286
Erik Kline1d065ba2016-06-08 13:24:45 +0900287 mDnsForwarders.clear();
San Mehat9d10b342010-01-18 09:51:02 -0800288 for (i = 0; i < numServers; i++) {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700289 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800290
Lorenzo Colittic2841282015-11-25 22:13:57 +0900291 addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST };
292 int ret = getaddrinfo(servers[i], NULL, &hints, &res);
293 freeaddrinfo(res);
294 if (ret) {
Steve Block5ea0c052012-01-06 19:18:11 +0000295 ALOGE("Failed to parse DNS server '%s'", servers[i]);
Erik Kline1d065ba2016-06-08 13:24:45 +0900296 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900297 errno = EINVAL;
San Mehat9d10b342010-01-18 09:51:02 -0800298 return -1;
299 }
Kenny Rootcf52faf2010-02-18 09:59:55 -0800300
Nick Kralevichad5b41f2012-07-19 18:48:05 -0700301 cmdLen += (strlen(servers[i]) + 1);
302 if (cmdLen + 1 >= MAX_CMD_SIZE) {
Steve Block7b984e32011-12-20 16:22:42 +0000303 ALOGD("Too many DNS servers listed");
Kenny Rootcf52faf2010-02-18 09:59:55 -0800304 break;
305 }
306
Erik Kline13fa01f2015-11-12 17:49:23 +0900307 strcat(daemonCmd, SEPARATOR);
San Mehat9d10b342010-01-18 09:51:02 -0800308 strcat(daemonCmd, servers[i]);
Erik Kline1d065ba2016-06-08 13:24:45 +0900309 mDnsForwarders.push_back(servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800310 }
311
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700312 mDnsNetId = netId;
San Mehat9d10b342010-01-18 09:51:02 -0800313 if (mDaemonFd != -1) {
Steve Block7b984e32011-12-20 16:22:42 +0000314 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
San Mehat9d10b342010-01-18 09:51:02 -0800315 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000316 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
Erik Kline1d065ba2016-06-08 13:24:45 +0900317 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900318 errno = EREMOTEIO;
San Mehat9d10b342010-01-18 09:51:02 -0800319 return -1;
320 }
321 }
322 return 0;
323}
324
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700325unsigned TetherController::getDnsNetId() {
326 return mDnsNetId;
327}
328
Erik Kline1d065ba2016-06-08 13:24:45 +0900329const std::list<std::string> &TetherController::getDnsForwarders() const {
San Mehat9d10b342010-01-18 09:51:02 -0800330 return mDnsForwarders;
331}
332
Erik Kline1d065ba2016-06-08 13:24:45 +0900333bool TetherController::applyDnsInterfaces() {
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800334 char daemonCmd[MAX_CMD_SIZE];
335
336 strcpy(daemonCmd, "update_ifaces");
337 int cmdLen = strlen(daemonCmd);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800338 bool haveInterfaces = false;
339
Erik Kline1d065ba2016-06-08 13:24:45 +0900340 for (const auto &ifname : mInterfaces) {
341 cmdLen += (ifname.size() + 1);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800342 if (cmdLen + 1 >= MAX_CMD_SIZE) {
343 ALOGD("Too many DNS ifaces listed");
344 break;
345 }
346
Erik Kline13fa01f2015-11-12 17:49:23 +0900347 strcat(daemonCmd, SEPARATOR);
Erik Kline1d065ba2016-06-08 13:24:45 +0900348 strcat(daemonCmd, ifname.c_str());
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800349 haveInterfaces = true;
350 }
351
352 if ((mDaemonFd != -1) && haveInterfaces) {
353 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
354 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
355 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
Erik Kline1d065ba2016-06-08 13:24:45 +0900356 return false;
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800357 }
358 }
Erik Kline1d065ba2016-06-08 13:24:45 +0900359 return true;
San Mehat9d10b342010-01-18 09:51:02 -0800360}
361
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800362int TetherController::tetherInterface(const char *interface) {
363 ALOGD("tetherInterface(%s)", interface);
JP Abgrall69261cb2014-06-19 18:35:24 -0700364 if (!isIfaceName(interface)) {
365 errno = ENOENT;
366 return -1;
367 }
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800368
Erik Kline1d065ba2016-06-08 13:24:45 +0900369 if (!configureForIPv6Router(interface)) {
370 configureForIPv6Client(interface);
371 return -1;
372 }
373 mInterfaces.push_back(interface);
374
375 if (!applyDnsInterfaces()) {
376 mInterfaces.pop_back();
377 configureForIPv6Client(interface);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800378 return -1;
379 } else {
380 return 0;
381 }
382}
383
San Mehat9d10b342010-01-18 09:51:02 -0800384int TetherController::untetherInterface(const char *interface) {
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800385 ALOGD("untetherInterface(%s)", interface);
386
Erik Kline1d065ba2016-06-08 13:24:45 +0900387 for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
388 if (!strcmp(interface, it->c_str())) {
389 mInterfaces.erase(it);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800390
Erik Kline1d065ba2016-06-08 13:24:45 +0900391 configureForIPv6Client(interface);
392 return applyDnsInterfaces() ? 0 : -1;
San Mehat9d10b342010-01-18 09:51:02 -0800393 }
394 }
395 errno = ENOENT;
396 return -1;
397}
398
Erik Kline1d065ba2016-06-08 13:24:45 +0900399const std::list<std::string> &TetherController::getTetheredInterfaceList() const {
San Mehat9d10b342010-01-18 09:51:02 -0800400 return mInterfaces;
401}
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900402
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900403int TetherController::setupIptablesHooks() {
404 int res;
405 res = setDefaults();
406 if (res < 0) {
407 return res;
408 }
409
410 // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large
411 // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA.
412 // This is no longer optional and tethering will fail to start if it fails.
413 std::string mssRewriteCommand = StringPrintf(
414 "*mangle\n"
415 "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n"
416 "COMMIT\n", LOCAL_MANGLE_FORWARD);
417
418 // This is for tethering counters. This chain is reached via --goto, and then RETURNS.
419 std::string defaultCommands = StringPrintf(
420 "*filter\n"
421 ":%s -\n"
422 "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN);
423
424 res = iptablesRestoreFunction(V4, mssRewriteCommand, nullptr);
425 if (res < 0) {
426 return res;
427 }
428
429 res = iptablesRestoreFunction(V4V6, defaultCommands, nullptr);
430 if (res < 0) {
431 return res;
432 }
433
434 ifacePairList.clear();
435
436 return 0;
437}
438
439int TetherController::setDefaults() {
440 std::string v4Cmd = StringPrintf(
441 "*filter\n"
442 ":%s -\n"
443 "-A %s -j DROP\n"
444 "COMMIT\n"
445 "*nat\n"
446 ":%s -\n"
447 "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING);
448
449 std::string v6Cmd = StringPrintf(
450 "*filter\n"
451 ":%s -\n"
452 "COMMIT\n"
453 "*raw\n"
454 ":%s -\n"
455 "COMMIT\n", LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
456
457 int res = iptablesRestoreFunction(V4, v4Cmd, nullptr);
458 if (res < 0) {
459 return res;
460 }
461
462 res = iptablesRestoreFunction(V6, v6Cmd, nullptr);
463 if (res < 0) {
464 return res;
465 }
466
467 natCount = 0;
468
469 return 0;
470}
471
472int TetherController::enableNat(const char* intIface, const char* extIface) {
473 ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
474
475 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
476 errno = ENODEV;
477 return -1;
478 }
479
480 /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */
481 if (!strcmp(intIface, extIface)) {
482 ALOGE("Duplicate interface specified: %s %s", intIface, extIface);
483 errno = EINVAL;
484 return -1;
485 }
486
487 // add this if we are the first added nat
488 if (natCount == 0) {
489 std::vector<std::string> v4Cmds = {
490 "*nat",
491 StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface),
492 "COMMIT\n"
493 };
494
495 /*
496 * IPv6 tethering doesn't need the state-based conntrack rules, so
497 * it unconditionally jumps to the tether counters chain all the time.
498 */
499 std::vector<std::string> v6Cmds = {
500 "*filter",
501 StringPrintf("-A %s -g %s", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN),
502 "COMMIT\n"
503 };
504
505 if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) ||
506 iptablesRestoreFunction(V6, Join(v6Cmds, '\n'), nullptr)) {
507 ALOGE("Error setting postroute rule: iface=%s", extIface);
508 // unwind what's been done, but don't care about success - what more could we do?
509 setDefaults();
510 return -1;
511 }
512 }
513
514 if (setForwardRules(true, intIface, extIface) != 0) {
515 ALOGE("Error setting forward rules");
516 if (natCount == 0) {
517 setDefaults();
518 }
519 errno = ENODEV;
520 return -1;
521 }
522
523 natCount++;
524 return 0;
525}
526
527bool TetherController::checkTetherCountingRuleExist(const std::string& pair_name) {
528 return std::find(ifacePairList.begin(), ifacePairList.end(), pair_name) != ifacePairList.end();
529}
530
531/* static */
532std::string TetherController::makeTetherCountingRule(const char *if1, const char *if2) {
533 return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2);
534}
535
536int TetherController::setForwardRules(bool add, const char *intIface, const char *extIface) {
537 const char *op = add ? "-A" : "-D";
538
539 std::string rpfilterCmd = StringPrintf(
540 "*raw\n"
541 "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
542 "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface);
543 if (iptablesRestoreFunction(V6, rpfilterCmd, nullptr) == -1 && add) {
544 return -1;
545 }
546
547 std::vector<std::string> v4 = {
548 "*filter",
549 StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s",
550 op, LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN),
551 StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP",
552 op, LOCAL_FORWARD, intIface, extIface),
553 StringPrintf("%s %s -i %s -o %s -g %s",
554 op, LOCAL_FORWARD, intIface, extIface, LOCAL_TETHER_COUNTERS_CHAIN),
555 };
556
557 std::vector<std::string> v6 = {
558 "*filter",
559 };
560
561 /* We only ever add tethering quota rules so that they stick. */
562 std::string pair1 = StringPrintf("%s_%s", intIface, extIface);
563 if (add && !checkTetherCountingRuleExist(pair1)) {
564 v4.push_back(makeTetherCountingRule(intIface, extIface));
565 v6.push_back(makeTetherCountingRule(intIface, extIface));
566 }
567 std::string pair2 = StringPrintf("%s_%s", extIface, intIface);
568 if (add && !checkTetherCountingRuleExist(pair2)) {
569 v4.push_back(makeTetherCountingRule(extIface, intIface));
570 v6.push_back(makeTetherCountingRule(extIface, intIface));
571 }
572
573 // Always make sure the drop rule is at the end.
574 // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900575 // every time, starting with ":tetherctrl_FORWARD -\n". This would likely be a bit simpler.
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900576 if (add) {
577 v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD));
578 v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD));
579 }
580
581 v4.push_back("COMMIT\n");
582 v6.push_back("COMMIT\n");
583
584 // We only add IPv6 rules here, never remove them.
585 if (iptablesRestoreFunction(V4, Join(v4, '\n'), nullptr) == -1 ||
586 (add && iptablesRestoreFunction(V6, Join(v6, '\n'), nullptr) == -1)) {
587 // unwind what's been done, but don't care about success - what more could we do?
588 if (add) {
589 setForwardRules(false, intIface, extIface);
590 }
591 return -1;
592 }
593
594 if (add && !checkTetherCountingRuleExist(pair1)) {
595 ifacePairList.push_front(pair1);
596 }
597 if (add && !checkTetherCountingRuleExist(pair2)) {
598 ifacePairList.push_front(pair2);
599 }
600
601 return 0;
602}
603
604int TetherController::disableNat(const char* intIface, const char* extIface) {
605 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
606 errno = ENODEV;
607 return -1;
608 }
609
610 setForwardRules(false, intIface, extIface);
611 if (--natCount <= 0) {
612 // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
613 setDefaults();
614 }
615 return 0;
616}
617
618void TetherController::addStats(TetherStatsList& statsList, const TetherStats& stats) {
619 for (TetherStats& existing : statsList) {
620 if (existing.addStatsIfMatch(stats)) {
621 return;
622 }
623 }
624 // No match. Insert a new interface pair.
625 statsList.push_back(stats);
626}
627
628/*
629 * Parse the ptks and bytes out of:
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900630 * Chain tetherctrl_counters (4 references)
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900631 * pkts bytes target prot opt in out source destination
632 * 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
633 * 27 2002 RETURN all -- rmnet0 wlan0 0.0.0.0/0 0.0.0.0/0
634 * 1040 107471 RETURN all -- bt-pan rmnet0 0.0.0.0/0 0.0.0.0/0
635 * 1450 1708806 RETURN all -- rmnet0 bt-pan 0.0.0.0/0 0.0.0.0/0
636 * or:
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900637 * Chain tetherctrl_counters (0 references)
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900638 * pkts bytes target prot opt in out source destination
639 * 0 0 RETURN all wlan0 rmnet_data0 ::/0 ::/0
640 * 0 0 RETURN all rmnet_data0 wlan0 ::/0 ::/0
641 *
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900642 */
Lorenzo Colitti09353392017-08-24 14:20:32 +0900643int TetherController::addForwardChainStats(TetherStatsList& statsList,
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900644 const std::string& statsOutput,
645 std::string &extraProcessingInfo) {
646 int res;
647 std::string statsLine;
648 char iface0[MAX_IPT_OUTPUT_LINE_LEN];
649 char iface1[MAX_IPT_OUTPUT_LINE_LEN];
650 char rest[MAX_IPT_OUTPUT_LINE_LEN];
651
652 TetherStats stats;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900653 const TetherStats empty;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900654 const char *buffPtr;
655 int64_t packets, bytes;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900656
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900657 std::stringstream stream(statsOutput);
Lorenzo Colitti09353392017-08-24 14:20:32 +0900658
659 // Skip headers.
660 for (int i = 0; i < 2; i++) {
661 std::getline(stream, statsLine, '\n');
662 extraProcessingInfo += statsLine + "\n";
663 if (statsLine.empty()) {
664 ALOGE("Empty header while parsing tethering stats");
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900665 return -EREMOTEIO;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900666 }
667 }
668
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900669 while (std::getline(stream, statsLine, '\n')) {
670 buffPtr = statsLine.c_str();
671
672 /* Clean up, so a failed parse can still print info */
673 iface0[0] = iface1[0] = rest[0] = packets = bytes = 0;
674 if (strstr(buffPtr, "0.0.0.0")) {
675 // IPv4 has -- indicating what to do with fragments...
676 // 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
677 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all -- %s %s 0.%s",
678 &packets, &bytes, iface0, iface1, rest);
679 } else {
680 // ... but IPv6 does not.
681 // 26 2373 RETURN all wlan0 rmnet0 ::/0 ::/0
682 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all %s %s ::/%s",
683 &packets, &bytes, iface0, iface1, rest);
684 }
685 ALOGV("parse res=%d iface0=<%s> iface1=<%s> pkts=%" PRId64" bytes=%" PRId64" rest=<%s> orig line=<%s>", res,
686 iface0, iface1, packets, bytes, rest, buffPtr);
687 extraProcessingInfo += buffPtr;
688 extraProcessingInfo += "\n";
689
690 if (res != 5) {
Lorenzo Colitti09353392017-08-24 14:20:32 +0900691 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900692 }
693 /*
694 * The following assumes that the 1st rule has in:extIface out:intIface,
695 * which is what TetherController sets up.
Lorenzo Colitti09353392017-08-24 14:20:32 +0900696 * The 1st matches rx, and sets up the pair for the tx side.
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900697 */
Lorenzo Colitti09353392017-08-24 14:20:32 +0900698 if (!stats.intIface[0]) {
699 ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
700 stats.intIface = iface0;
701 stats.extIface = iface1;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900702 stats.txPackets = packets;
703 stats.txBytes = bytes;
Lorenzo Colitti9a65ac62017-09-04 18:07:56 +0900704 } else if (stats.intIface == iface1 && stats.extIface == iface0) {
705 ALOGV("0Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
706 stats.rxPackets = packets;
707 stats.rxBytes = bytes;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900708 }
709 if (stats.rxBytes != -1 && stats.txBytes != -1) {
Lorenzo Colitti09353392017-08-24 14:20:32 +0900710 ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64, stats.rxBytes, stats.txBytes);
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900711 addStats(statsList, stats);
Lorenzo Colitti09353392017-08-24 14:20:32 +0900712 stats = empty;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900713 }
714 }
715
716 /* It is always an error to find only one side of the stats. */
Lorenzo Colitti38fd1362017-09-15 11:40:01 +0900717 if (((stats.rxBytes == -1) != (stats.txBytes == -1))) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900718 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900719 }
720 return 0;
721}
722
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900723StatusOr<TetherController::TetherStatsList> TetherController::getTetherStats() {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900724 TetherStatsList statsList;
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900725 std::string parsedIptablesOutput;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900726
727 for (const IptablesTarget target : {V4, V6}) {
728 std::string statsString;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900729 if (int ret = iptablesRestoreFunction(target, GET_TETHER_STATS_COMMAND, &statsString)) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900730 return statusFromErrno(-ret, StringPrintf("failed to fetch tether stats (%d): %d",
731 target, ret));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900732 }
733
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900734 if (int ret = addForwardChainStats(statsList, statsString, parsedIptablesOutput)) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900735 return statusFromErrno(-ret, StringPrintf("failed to parse %s tether stats:\n%s",
736 target == V4 ? "IPv4": "IPv6",
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900737 parsedIptablesOutput.c_str()));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900738 }
739 }
740
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900741 return statsList;
742}
743
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900744} // namespace net
745} // namespace android