blob: baf477af8a954b82760af1da76d2a015421e644f [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[] = "|";
Lorenzo Colitti799625c2015-02-25 12:52:00 +090059
60bool writeToFile(const char* filename, const char* value) {
Nick Kralevichb95c60c2016-11-19 09:09:16 -080061 int fd = open(filename, O_WRONLY | O_CLOEXEC);
Nicolas Geoffrayafd40372015-03-16 11:58:06 +000062 if (fd < 0) {
63 ALOGE("Failed to open %s: %s", filename, strerror(errno));
64 return false;
65 }
66
67 const ssize_t len = strlen(value);
68 if (write(fd, value, len) != len) {
69 ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
70 close(fd);
71 return false;
72 }
73 close(fd);
74 return true;
Lorenzo Colitti799625c2015-02-25 12:52:00 +090075}
76
Erik Kline1d065ba2016-06-08 13:24:45 +090077bool configureForIPv6Router(const char *interface) {
78 return (InterfaceController::setEnableIPv6(interface, 0) == 0)
79 && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
Erik Kline6cddf512016-08-09 15:28:42 +090080 && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0)
81 && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0)
Erik Kline1d065ba2016-06-08 13:24:45 +090082 && (InterfaceController::setEnableIPv6(interface, 1) == 0);
83}
84
85void configureForIPv6Client(const char *interface) {
86 InterfaceController::setAcceptIPv6Ra(interface, 1);
Erik Kline6cddf512016-08-09 15:28:42 +090087 InterfaceController::setAcceptIPv6Dad(interface, 1);
88 InterfaceController::setIPv6DadTransmits(interface, "1");
Erik Kline1d065ba2016-06-08 13:24:45 +090089 InterfaceController::setEnableIPv6(interface, 0);
90}
91
Lorenzo Colitti799625c2015-02-25 12:52:00 +090092bool inBpToolsMode() {
93 // In BP tools mode, do not disable IP forwarding
94 char bootmode[PROPERTY_VALUE_MAX] = {0};
95 property_get("ro.bootmode", bootmode, "unknown");
96 return !strcmp(BP_TOOLS_MODE, bootmode);
97}
98
99} // namespace
100
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900101namespace android {
102namespace net {
103
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900104auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
105
106const int MAX_IPT_OUTPUT_LINE_LEN = 256;
107
108const std::string GET_TETHER_STATS_COMMAND = StringPrintf(
109 "*filter\n"
110 "-nvx -L %s\n"
111 "COMMIT\n", android::net::TetherController::LOCAL_TETHER_COUNTERS_CHAIN);
112
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700113TetherController::TetherController() {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700114 mDnsNetId = 0;
San Mehat9d10b342010-01-18 09:51:02 -0800115 mDaemonFd = -1;
116 mDaemonPid = 0;
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900117 if (inBpToolsMode()) {
118 enableForwarding(BP_TOOLS_MODE);
119 } else {
120 setIpFwdEnabled();
121 }
San Mehat9d10b342010-01-18 09:51:02 -0800122}
123
124TetherController::~TetherController() {
Erik Kline1d065ba2016-06-08 13:24:45 +0900125 mInterfaces.clear();
126 mDnsForwarders.clear();
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900127 mForwardingRequests.clear();
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900128 ifacePairList.clear();
San Mehat9d10b342010-01-18 09:51:02 -0800129}
130
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900131bool TetherController::setIpFwdEnabled() {
132 bool success = true;
133 const char* value = mForwardingRequests.empty() ? "0" : "1";
134 ALOGD("Setting IP forward enable = %s", value);
135 success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
136 success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
137 return success;
San Mehat9d10b342010-01-18 09:51:02 -0800138}
139
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900140bool TetherController::enableForwarding(const char* requester) {
141 // Don't return an error if this requester already requested forwarding. Only return errors for
142 // things that the caller caller needs to care about, such as "couldn't write to the file to
143 // enable forwarding".
144 mForwardingRequests.insert(requester);
145 return setIpFwdEnabled();
146}
San Mehat9d10b342010-01-18 09:51:02 -0800147
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900148bool TetherController::disableForwarding(const char* requester) {
149 mForwardingRequests.erase(requester);
150 return setIpFwdEnabled();
151}
San Mehat9d10b342010-01-18 09:51:02 -0800152
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900153size_t TetherController::forwardingRequestCount() {
154 return mForwardingRequests.size();
San Mehat9d10b342010-01-18 09:51:02 -0800155}
156
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900157#define TETHER_START_CONST_ARG 10
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800158
Erik Kline13fa01f2015-11-12 17:49:23 +0900159int TetherController::startTethering(int num_addrs, char **dhcp_ranges) {
San Mehat9d10b342010-01-18 09:51:02 -0800160 if (mDaemonPid != 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000161 ALOGE("Tethering already started");
San Mehat9d10b342010-01-18 09:51:02 -0800162 errno = EBUSY;
163 return -1;
164 }
165
Steve Block7b984e32011-12-20 16:22:42 +0000166 ALOGD("Starting tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800167
168 pid_t pid;
169 int pipefd[2];
170
171 if (pipe(pipefd) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000172 ALOGE("pipe failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800173 return -1;
174 }
175
176 /*
177 * TODO: Create a monitoring thread to handle and restart
178 * the daemon if it exits prematurely
179 */
180 if ((pid = fork()) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000181 ALOGE("fork failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800182 close(pipefd[0]);
183 close(pipefd[1]);
184 return -1;
185 }
186
187 if (!pid) {
188 close(pipefd[1]);
189 if (pipefd[0] != STDIN_FILENO) {
190 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
Steve Block5ea0c052012-01-06 19:18:11 +0000191 ALOGE("dup2 failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800192 return -1;
193 }
194 close(pipefd[0]);
195 }
San Mehat9d10b342010-01-18 09:51:02 -0800196
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900197 Fwmark fwmark;
198 fwmark.netId = NetworkController::LOCAL_NET_ID;
199 fwmark.explicitlySelected = true;
200 fwmark.protectedFromVpn = true;
201 fwmark.permission = PERMISSION_SYSTEM;
202 char markStr[UINT32_HEX_STRLEN];
203 snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue);
204
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800205 int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1;
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700206 char **args = (char **)malloc(sizeof(char *) * num_processed_args);
207 args[num_processed_args - 1] = NULL;
208 args[0] = (char *)"/system/bin/dnsmasq";
Peter Nilssonb756f692011-09-08 09:48:31 -0700209 args[1] = (char *)"--keep-in-foreground";
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700210 args[2] = (char *)"--no-resolv";
211 args[3] = (char *)"--no-poll";
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800212 args[4] = (char *)"--dhcp-authoritative";
Jeff Sharkey6df79da2012-04-18 21:53:35 -0700213 // TODO: pipe through metered status from ConnService
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800214 args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
215 args[6] = (char *)"--pid-file";
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900216 args[7] = (char *)"--listen-mark";
217 args[8] = (char *)markStr;
218 args[9] = (char *)"";
San Mehat9d10b342010-01-18 09:51:02 -0800219
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800220 int nextArg = TETHER_START_CONST_ARG;
Erik Kline13fa01f2015-11-12 17:49:23 +0900221 for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
222 asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h",
223 dhcp_ranges[addrIndex], dhcp_ranges[addrIndex+1]);
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700224 }
225
226 if (execv(args[0], args)) {
Steve Block5ea0c052012-01-06 19:18:11 +0000227 ALOGE("execl failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800228 }
Steve Block5ea0c052012-01-06 19:18:11 +0000229 ALOGE("Should never get here!");
JP Abgrallce4f3792012-08-06 13:44:44 -0700230 _exit(-1);
San Mehat9d10b342010-01-18 09:51:02 -0800231 } else {
232 close(pipefd[0]);
233 mDaemonPid = pid;
234 mDaemonFd = pipefd[1];
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800235 applyDnsInterfaces();
Steve Block7b984e32011-12-20 16:22:42 +0000236 ALOGD("Tethering services running");
San Mehat9d10b342010-01-18 09:51:02 -0800237 }
238
239 return 0;
240}
241
242int TetherController::stopTethering() {
243
244 if (mDaemonPid == 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000245 ALOGE("Tethering already stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800246 return 0;
247 }
248
Steve Block7b984e32011-12-20 16:22:42 +0000249 ALOGD("Stopping tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800250
251 kill(mDaemonPid, SIGTERM);
San Mehat18737842010-01-21 09:22:43 -0800252 waitpid(mDaemonPid, NULL, 0);
San Mehat9d10b342010-01-18 09:51:02 -0800253 mDaemonPid = 0;
254 close(mDaemonFd);
255 mDaemonFd = -1;
Steve Block7b984e32011-12-20 16:22:42 +0000256 ALOGD("Tethering services stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800257 return 0;
258}
Matthew Xie19944102012-07-12 16:42:07 -0700259
San Mehat9d10b342010-01-18 09:51:02 -0800260bool TetherController::isTetheringStarted() {
261 return (mDaemonPid == 0 ? false : true);
262}
263
Kenny Rootcf52faf2010-02-18 09:59:55 -0800264#define MAX_CMD_SIZE 1024
265
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700266int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
San Mehat9d10b342010-01-18 09:51:02 -0800267 int i;
Kenny Rootcf52faf2010-02-18 09:59:55 -0800268 char daemonCmd[MAX_CMD_SIZE];
San Mehat9d10b342010-01-18 09:51:02 -0800269
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700270 Fwmark fwmark;
271 fwmark.netId = netId;
272 fwmark.explicitlySelected = true;
273 fwmark.protectedFromVpn = true;
274 fwmark.permission = PERMISSION_SYSTEM;
275
Erik Kline13fa01f2015-11-12 17:49:23 +0900276 snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue);
Kenny Rootcf52faf2010-02-18 09:59:55 -0800277 int cmdLen = strlen(daemonCmd);
San Mehat9d10b342010-01-18 09:51:02 -0800278
Erik Kline1d065ba2016-06-08 13:24:45 +0900279 mDnsForwarders.clear();
San Mehat9d10b342010-01-18 09:51:02 -0800280 for (i = 0; i < numServers; i++) {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700281 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800282
Lorenzo Colittic2841282015-11-25 22:13:57 +0900283 addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST };
284 int ret = getaddrinfo(servers[i], NULL, &hints, &res);
285 freeaddrinfo(res);
286 if (ret) {
Steve Block5ea0c052012-01-06 19:18:11 +0000287 ALOGE("Failed to parse DNS server '%s'", servers[i]);
Erik Kline1d065ba2016-06-08 13:24:45 +0900288 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900289 errno = EINVAL;
San Mehat9d10b342010-01-18 09:51:02 -0800290 return -1;
291 }
Kenny Rootcf52faf2010-02-18 09:59:55 -0800292
Nick Kralevichad5b41f2012-07-19 18:48:05 -0700293 cmdLen += (strlen(servers[i]) + 1);
294 if (cmdLen + 1 >= MAX_CMD_SIZE) {
Steve Block7b984e32011-12-20 16:22:42 +0000295 ALOGD("Too many DNS servers listed");
Kenny Rootcf52faf2010-02-18 09:59:55 -0800296 break;
297 }
298
Erik Kline13fa01f2015-11-12 17:49:23 +0900299 strcat(daemonCmd, SEPARATOR);
San Mehat9d10b342010-01-18 09:51:02 -0800300 strcat(daemonCmd, servers[i]);
Erik Kline1d065ba2016-06-08 13:24:45 +0900301 mDnsForwarders.push_back(servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800302 }
303
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700304 mDnsNetId = netId;
San Mehat9d10b342010-01-18 09:51:02 -0800305 if (mDaemonFd != -1) {
Steve Block7b984e32011-12-20 16:22:42 +0000306 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
San Mehat9d10b342010-01-18 09:51:02 -0800307 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000308 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
Erik Kline1d065ba2016-06-08 13:24:45 +0900309 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900310 errno = EREMOTEIO;
San Mehat9d10b342010-01-18 09:51:02 -0800311 return -1;
312 }
313 }
314 return 0;
315}
316
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700317unsigned TetherController::getDnsNetId() {
318 return mDnsNetId;
319}
320
Erik Kline1d065ba2016-06-08 13:24:45 +0900321const std::list<std::string> &TetherController::getDnsForwarders() const {
San Mehat9d10b342010-01-18 09:51:02 -0800322 return mDnsForwarders;
323}
324
Erik Kline1d065ba2016-06-08 13:24:45 +0900325bool TetherController::applyDnsInterfaces() {
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800326 char daemonCmd[MAX_CMD_SIZE];
327
328 strcpy(daemonCmd, "update_ifaces");
329 int cmdLen = strlen(daemonCmd);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800330 bool haveInterfaces = false;
331
Erik Kline1d065ba2016-06-08 13:24:45 +0900332 for (const auto &ifname : mInterfaces) {
333 cmdLen += (ifname.size() + 1);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800334 if (cmdLen + 1 >= MAX_CMD_SIZE) {
335 ALOGD("Too many DNS ifaces listed");
336 break;
337 }
338
Erik Kline13fa01f2015-11-12 17:49:23 +0900339 strcat(daemonCmd, SEPARATOR);
Erik Kline1d065ba2016-06-08 13:24:45 +0900340 strcat(daemonCmd, ifname.c_str());
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800341 haveInterfaces = true;
342 }
343
344 if ((mDaemonFd != -1) && haveInterfaces) {
345 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
346 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
347 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
Erik Kline1d065ba2016-06-08 13:24:45 +0900348 return false;
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800349 }
350 }
Erik Kline1d065ba2016-06-08 13:24:45 +0900351 return true;
San Mehat9d10b342010-01-18 09:51:02 -0800352}
353
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800354int TetherController::tetherInterface(const char *interface) {
355 ALOGD("tetherInterface(%s)", interface);
JP Abgrall69261cb2014-06-19 18:35:24 -0700356 if (!isIfaceName(interface)) {
357 errno = ENOENT;
358 return -1;
359 }
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800360
Erik Kline1d065ba2016-06-08 13:24:45 +0900361 if (!configureForIPv6Router(interface)) {
362 configureForIPv6Client(interface);
363 return -1;
364 }
365 mInterfaces.push_back(interface);
366
367 if (!applyDnsInterfaces()) {
368 mInterfaces.pop_back();
369 configureForIPv6Client(interface);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800370 return -1;
371 } else {
372 return 0;
373 }
374}
375
San Mehat9d10b342010-01-18 09:51:02 -0800376int TetherController::untetherInterface(const char *interface) {
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800377 ALOGD("untetherInterface(%s)", interface);
378
Erik Kline1d065ba2016-06-08 13:24:45 +0900379 for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
380 if (!strcmp(interface, it->c_str())) {
381 mInterfaces.erase(it);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800382
Erik Kline1d065ba2016-06-08 13:24:45 +0900383 configureForIPv6Client(interface);
384 return applyDnsInterfaces() ? 0 : -1;
San Mehat9d10b342010-01-18 09:51:02 -0800385 }
386 }
387 errno = ENOENT;
388 return -1;
389}
390
Erik Kline1d065ba2016-06-08 13:24:45 +0900391const std::list<std::string> &TetherController::getTetheredInterfaceList() const {
San Mehat9d10b342010-01-18 09:51:02 -0800392 return mInterfaces;
393}
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900394
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900395int TetherController::setupIptablesHooks() {
396 int res;
397 res = setDefaults();
398 if (res < 0) {
399 return res;
400 }
401
402 // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large
403 // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA.
404 // This is no longer optional and tethering will fail to start if it fails.
405 std::string mssRewriteCommand = StringPrintf(
406 "*mangle\n"
407 "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n"
408 "COMMIT\n", LOCAL_MANGLE_FORWARD);
409
410 // This is for tethering counters. This chain is reached via --goto, and then RETURNS.
411 std::string defaultCommands = StringPrintf(
412 "*filter\n"
413 ":%s -\n"
414 "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN);
415
416 res = iptablesRestoreFunction(V4, mssRewriteCommand, nullptr);
417 if (res < 0) {
418 return res;
419 }
420
421 res = iptablesRestoreFunction(V4V6, defaultCommands, nullptr);
422 if (res < 0) {
423 return res;
424 }
425
426 ifacePairList.clear();
427
428 return 0;
429}
430
431int TetherController::setDefaults() {
432 std::string v4Cmd = StringPrintf(
433 "*filter\n"
434 ":%s -\n"
435 "-A %s -j DROP\n"
436 "COMMIT\n"
437 "*nat\n"
438 ":%s -\n"
439 "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING);
440
441 std::string v6Cmd = StringPrintf(
442 "*filter\n"
443 ":%s -\n"
444 "COMMIT\n"
445 "*raw\n"
446 ":%s -\n"
447 "COMMIT\n", LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
448
449 int res = iptablesRestoreFunction(V4, v4Cmd, nullptr);
450 if (res < 0) {
451 return res;
452 }
453
454 res = iptablesRestoreFunction(V6, v6Cmd, nullptr);
455 if (res < 0) {
456 return res;
457 }
458
459 natCount = 0;
460
461 return 0;
462}
463
464int TetherController::enableNat(const char* intIface, const char* extIface) {
465 ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
466
467 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
468 errno = ENODEV;
469 return -1;
470 }
471
472 /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */
473 if (!strcmp(intIface, extIface)) {
474 ALOGE("Duplicate interface specified: %s %s", intIface, extIface);
475 errno = EINVAL;
476 return -1;
477 }
478
479 // add this if we are the first added nat
480 if (natCount == 0) {
481 std::vector<std::string> v4Cmds = {
482 "*nat",
483 StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface),
484 "COMMIT\n"
485 };
486
487 /*
488 * IPv6 tethering doesn't need the state-based conntrack rules, so
489 * it unconditionally jumps to the tether counters chain all the time.
490 */
491 std::vector<std::string> v6Cmds = {
492 "*filter",
493 StringPrintf("-A %s -g %s", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN),
494 "COMMIT\n"
495 };
496
497 if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) ||
498 iptablesRestoreFunction(V6, Join(v6Cmds, '\n'), nullptr)) {
499 ALOGE("Error setting postroute rule: iface=%s", extIface);
500 // unwind what's been done, but don't care about success - what more could we do?
501 setDefaults();
502 return -1;
503 }
504 }
505
506 if (setForwardRules(true, intIface, extIface) != 0) {
507 ALOGE("Error setting forward rules");
508 if (natCount == 0) {
509 setDefaults();
510 }
511 errno = ENODEV;
512 return -1;
513 }
514
515 natCount++;
516 return 0;
517}
518
519bool TetherController::checkTetherCountingRuleExist(const std::string& pair_name) {
520 return std::find(ifacePairList.begin(), ifacePairList.end(), pair_name) != ifacePairList.end();
521}
522
523/* static */
524std::string TetherController::makeTetherCountingRule(const char *if1, const char *if2) {
525 return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2);
526}
527
528int TetherController::setForwardRules(bool add, const char *intIface, const char *extIface) {
529 const char *op = add ? "-A" : "-D";
530
531 std::string rpfilterCmd = StringPrintf(
532 "*raw\n"
533 "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
534 "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface);
535 if (iptablesRestoreFunction(V6, rpfilterCmd, nullptr) == -1 && add) {
536 return -1;
537 }
538
539 std::vector<std::string> v4 = {
540 "*filter",
541 StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s",
542 op, LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN),
543 StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP",
544 op, LOCAL_FORWARD, intIface, extIface),
545 StringPrintf("%s %s -i %s -o %s -g %s",
546 op, LOCAL_FORWARD, intIface, extIface, LOCAL_TETHER_COUNTERS_CHAIN),
547 };
548
549 std::vector<std::string> v6 = {
550 "*filter",
551 };
552
553 /* We only ever add tethering quota rules so that they stick. */
554 std::string pair1 = StringPrintf("%s_%s", intIface, extIface);
555 if (add && !checkTetherCountingRuleExist(pair1)) {
556 v4.push_back(makeTetherCountingRule(intIface, extIface));
557 v6.push_back(makeTetherCountingRule(intIface, extIface));
558 }
559 std::string pair2 = StringPrintf("%s_%s", extIface, intIface);
560 if (add && !checkTetherCountingRuleExist(pair2)) {
561 v4.push_back(makeTetherCountingRule(extIface, intIface));
562 v6.push_back(makeTetherCountingRule(extIface, intIface));
563 }
564
565 // Always make sure the drop rule is at the end.
566 // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900567 // every time, starting with ":tetherctrl_FORWARD -\n". This would likely be a bit simpler.
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900568 if (add) {
569 v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD));
570 v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD));
571 }
572
573 v4.push_back("COMMIT\n");
574 v6.push_back("COMMIT\n");
575
576 // We only add IPv6 rules here, never remove them.
577 if (iptablesRestoreFunction(V4, Join(v4, '\n'), nullptr) == -1 ||
578 (add && iptablesRestoreFunction(V6, Join(v6, '\n'), nullptr) == -1)) {
579 // unwind what's been done, but don't care about success - what more could we do?
580 if (add) {
581 setForwardRules(false, intIface, extIface);
582 }
583 return -1;
584 }
585
586 if (add && !checkTetherCountingRuleExist(pair1)) {
587 ifacePairList.push_front(pair1);
588 }
589 if (add && !checkTetherCountingRuleExist(pair2)) {
590 ifacePairList.push_front(pair2);
591 }
592
593 return 0;
594}
595
596int TetherController::disableNat(const char* intIface, const char* extIface) {
597 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
598 errno = ENODEV;
599 return -1;
600 }
601
602 setForwardRules(false, intIface, extIface);
603 if (--natCount <= 0) {
604 // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
605 setDefaults();
606 }
607 return 0;
608}
609
610void TetherController::addStats(TetherStatsList& statsList, const TetherStats& stats) {
611 for (TetherStats& existing : statsList) {
612 if (existing.addStatsIfMatch(stats)) {
613 return;
614 }
615 }
616 // No match. Insert a new interface pair.
617 statsList.push_back(stats);
618}
619
620/*
621 * Parse the ptks and bytes out of:
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900622 * Chain tetherctrl_counters (4 references)
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900623 * pkts bytes target prot opt in out source destination
624 * 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
625 * 27 2002 RETURN all -- rmnet0 wlan0 0.0.0.0/0 0.0.0.0/0
626 * 1040 107471 RETURN all -- bt-pan rmnet0 0.0.0.0/0 0.0.0.0/0
627 * 1450 1708806 RETURN all -- rmnet0 bt-pan 0.0.0.0/0 0.0.0.0/0
628 * or:
Lorenzo Colitti4604b4a2017-08-24 19:21:50 +0900629 * Chain tetherctrl_counters (0 references)
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900630 * pkts bytes target prot opt in out source destination
631 * 0 0 RETURN all wlan0 rmnet_data0 ::/0 ::/0
632 * 0 0 RETURN all rmnet_data0 wlan0 ::/0 ::/0
633 *
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900634 */
Lorenzo Colitti09353392017-08-24 14:20:32 +0900635int TetherController::addForwardChainStats(TetherStatsList& statsList,
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900636 const std::string& statsOutput,
637 std::string &extraProcessingInfo) {
638 int res;
639 std::string statsLine;
640 char iface0[MAX_IPT_OUTPUT_LINE_LEN];
641 char iface1[MAX_IPT_OUTPUT_LINE_LEN];
642 char rest[MAX_IPT_OUTPUT_LINE_LEN];
643
644 TetherStats stats;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900645 const TetherStats empty;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900646 const char *buffPtr;
647 int64_t packets, bytes;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900648
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900649 std::stringstream stream(statsOutput);
Lorenzo Colitti09353392017-08-24 14:20:32 +0900650
651 // Skip headers.
652 for (int i = 0; i < 2; i++) {
653 std::getline(stream, statsLine, '\n');
654 extraProcessingInfo += statsLine + "\n";
655 if (statsLine.empty()) {
656 ALOGE("Empty header while parsing tethering stats");
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900657 return -EREMOTEIO;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900658 }
659 }
660
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900661 while (std::getline(stream, statsLine, '\n')) {
662 buffPtr = statsLine.c_str();
663
664 /* Clean up, so a failed parse can still print info */
665 iface0[0] = iface1[0] = rest[0] = packets = bytes = 0;
666 if (strstr(buffPtr, "0.0.0.0")) {
667 // IPv4 has -- indicating what to do with fragments...
668 // 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
669 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all -- %s %s 0.%s",
670 &packets, &bytes, iface0, iface1, rest);
671 } else {
672 // ... but IPv6 does not.
673 // 26 2373 RETURN all wlan0 rmnet0 ::/0 ::/0
674 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all %s %s ::/%s",
675 &packets, &bytes, iface0, iface1, rest);
676 }
677 ALOGV("parse res=%d iface0=<%s> iface1=<%s> pkts=%" PRId64" bytes=%" PRId64" rest=<%s> orig line=<%s>", res,
678 iface0, iface1, packets, bytes, rest, buffPtr);
679 extraProcessingInfo += buffPtr;
680 extraProcessingInfo += "\n";
681
682 if (res != 5) {
Lorenzo Colitti09353392017-08-24 14:20:32 +0900683 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900684 }
685 /*
686 * The following assumes that the 1st rule has in:extIface out:intIface,
687 * which is what TetherController sets up.
Lorenzo Colitti09353392017-08-24 14:20:32 +0900688 * The 1st matches rx, and sets up the pair for the tx side.
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900689 */
Lorenzo Colitti09353392017-08-24 14:20:32 +0900690 if (!stats.intIface[0]) {
691 ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
692 stats.intIface = iface0;
693 stats.extIface = iface1;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900694 stats.txPackets = packets;
695 stats.txBytes = bytes;
Lorenzo Colitti9a65ac62017-09-04 18:07:56 +0900696 } else if (stats.intIface == iface1 && stats.extIface == iface0) {
697 ALOGV("0Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
698 stats.rxPackets = packets;
699 stats.rxBytes = bytes;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900700 }
701 if (stats.rxBytes != -1 && stats.txBytes != -1) {
Lorenzo Colitti09353392017-08-24 14:20:32 +0900702 ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64, stats.rxBytes, stats.txBytes);
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900703 addStats(statsList, stats);
Lorenzo Colitti09353392017-08-24 14:20:32 +0900704 stats = empty;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900705 }
706 }
707
708 /* It is always an error to find only one side of the stats. */
Lorenzo Colitti38fd1362017-09-15 11:40:01 +0900709 if (((stats.rxBytes == -1) != (stats.txBytes == -1))) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900710 return -EREMOTEIO;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900711 }
712 return 0;
713}
714
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900715StatusOr<TetherController::TetherStatsList> TetherController::getTetherStats() {
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900716 TetherStatsList statsList;
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900717 std::string parsedIptablesOutput;
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900718
719 for (const IptablesTarget target : {V4, V6}) {
720 std::string statsString;
Lorenzo Colitti09353392017-08-24 14:20:32 +0900721 if (int ret = iptablesRestoreFunction(target, GET_TETHER_STATS_COMMAND, &statsString)) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900722 return statusFromErrno(-ret, StringPrintf("failed to fetch tether stats (%d): %d",
723 target, ret));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900724 }
725
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900726 if (int ret = addForwardChainStats(statsList, statsString, parsedIptablesOutput)) {
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900727 return statusFromErrno(-ret, StringPrintf("failed to parse %s tether stats:\n%s",
728 target == V4 ? "IPv4": "IPv6",
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900729 parsedIptablesOutput.c_str()));
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900730 }
731 }
732
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900733 return statsList;
734}
735
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900736} // namespace net
737} // namespace android