blob: 094170fdcc7a457248738fc6184b87ef4c46a4e0 [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>
San Mehat9d10b342010-01-18 09:51:02 -080037
Lorenzo Colitti667c4772014-08-26 14:13:07 -070038#include "Fwmark.h"
JP Abgrall69261cb2014-06-19 18:35:24 -070039#include "NetdConstants.h"
Lorenzo Colitti667c4772014-08-26 14:13:07 -070040#include "Permission.h"
Erik Kline1d065ba2016-06-08 13:24:45 +090041#include "InterfaceController.h"
Lorenzo Colittie20a5262017-05-09 18:30:44 +090042#include "NetworkController.h"
Lorenzo Colittia93126d2017-08-24 13:28:19 +090043#include "ResponseCode.h"
San Mehat9d10b342010-01-18 09:51:02 -080044#include "TetherController.h"
45
Lorenzo Colittia93126d2017-08-24 13:28:19 +090046using android::base::Join;
47using android::base::StringPrintf;
48using android::base::StringAppendF;
49
Lorenzo Colitti799625c2015-02-25 12:52:00 +090050namespace {
51
Erik Kline1d065ba2016-06-08 13:24:45 +090052const char BP_TOOLS_MODE[] = "bp-tools";
53const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
54const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
55const char SEPARATOR[] = "|";
Lorenzo Colitti799625c2015-02-25 12:52:00 +090056
57bool writeToFile(const char* filename, const char* value) {
Nick Kralevichb95c60c2016-11-19 09:09:16 -080058 int fd = open(filename, O_WRONLY | O_CLOEXEC);
Nicolas Geoffrayafd40372015-03-16 11:58:06 +000059 if (fd < 0) {
60 ALOGE("Failed to open %s: %s", filename, strerror(errno));
61 return false;
62 }
63
64 const ssize_t len = strlen(value);
65 if (write(fd, value, len) != len) {
66 ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
67 close(fd);
68 return false;
69 }
70 close(fd);
71 return true;
Lorenzo Colitti799625c2015-02-25 12:52:00 +090072}
73
Erik Kline1d065ba2016-06-08 13:24:45 +090074bool configureForIPv6Router(const char *interface) {
75 return (InterfaceController::setEnableIPv6(interface, 0) == 0)
76 && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
Erik Kline6cddf512016-08-09 15:28:42 +090077 && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0)
78 && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0)
Erik Kline1d065ba2016-06-08 13:24:45 +090079 && (InterfaceController::setEnableIPv6(interface, 1) == 0);
80}
81
82void configureForIPv6Client(const char *interface) {
83 InterfaceController::setAcceptIPv6Ra(interface, 1);
Erik Kline6cddf512016-08-09 15:28:42 +090084 InterfaceController::setAcceptIPv6Dad(interface, 1);
85 InterfaceController::setIPv6DadTransmits(interface, "1");
Erik Kline1d065ba2016-06-08 13:24:45 +090086 InterfaceController::setEnableIPv6(interface, 0);
87}
88
Lorenzo Colitti799625c2015-02-25 12:52:00 +090089bool inBpToolsMode() {
90 // In BP tools mode, do not disable IP forwarding
91 char bootmode[PROPERTY_VALUE_MAX] = {0};
92 property_get("ro.bootmode", bootmode, "unknown");
93 return !strcmp(BP_TOOLS_MODE, bootmode);
94}
95
96} // namespace
97
Lorenzo Colittie20a5262017-05-09 18:30:44 +090098namespace android {
99namespace net {
100
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900101auto TetherController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
102
103const int MAX_IPT_OUTPUT_LINE_LEN = 256;
104
105const std::string GET_TETHER_STATS_COMMAND = StringPrintf(
106 "*filter\n"
107 "-nvx -L %s\n"
108 "COMMIT\n", android::net::TetherController::LOCAL_TETHER_COUNTERS_CHAIN);
109
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700110TetherController::TetherController() {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700111 mDnsNetId = 0;
San Mehat9d10b342010-01-18 09:51:02 -0800112 mDaemonFd = -1;
113 mDaemonPid = 0;
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900114 if (inBpToolsMode()) {
115 enableForwarding(BP_TOOLS_MODE);
116 } else {
117 setIpFwdEnabled();
118 }
San Mehat9d10b342010-01-18 09:51:02 -0800119}
120
121TetherController::~TetherController() {
Erik Kline1d065ba2016-06-08 13:24:45 +0900122 mInterfaces.clear();
123 mDnsForwarders.clear();
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900124 mForwardingRequests.clear();
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900125 ifacePairList.clear();
San Mehat9d10b342010-01-18 09:51:02 -0800126}
127
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900128bool TetherController::setIpFwdEnabled() {
129 bool success = true;
130 const char* value = mForwardingRequests.empty() ? "0" : "1";
131 ALOGD("Setting IP forward enable = %s", value);
132 success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
133 success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
134 return success;
San Mehat9d10b342010-01-18 09:51:02 -0800135}
136
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900137bool TetherController::enableForwarding(const char* requester) {
138 // Don't return an error if this requester already requested forwarding. Only return errors for
139 // things that the caller caller needs to care about, such as "couldn't write to the file to
140 // enable forwarding".
141 mForwardingRequests.insert(requester);
142 return setIpFwdEnabled();
143}
San Mehat9d10b342010-01-18 09:51:02 -0800144
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900145bool TetherController::disableForwarding(const char* requester) {
146 mForwardingRequests.erase(requester);
147 return setIpFwdEnabled();
148}
San Mehat9d10b342010-01-18 09:51:02 -0800149
Lorenzo Colitti799625c2015-02-25 12:52:00 +0900150size_t TetherController::forwardingRequestCount() {
151 return mForwardingRequests.size();
San Mehat9d10b342010-01-18 09:51:02 -0800152}
153
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900154#define TETHER_START_CONST_ARG 10
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800155
Erik Kline13fa01f2015-11-12 17:49:23 +0900156int TetherController::startTethering(int num_addrs, char **dhcp_ranges) {
San Mehat9d10b342010-01-18 09:51:02 -0800157 if (mDaemonPid != 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000158 ALOGE("Tethering already started");
San Mehat9d10b342010-01-18 09:51:02 -0800159 errno = EBUSY;
160 return -1;
161 }
162
Steve Block7b984e32011-12-20 16:22:42 +0000163 ALOGD("Starting tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800164
165 pid_t pid;
166 int pipefd[2];
167
168 if (pipe(pipefd) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000169 ALOGE("pipe failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800170 return -1;
171 }
172
173 /*
174 * TODO: Create a monitoring thread to handle and restart
175 * the daemon if it exits prematurely
176 */
177 if ((pid = fork()) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000178 ALOGE("fork failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800179 close(pipefd[0]);
180 close(pipefd[1]);
181 return -1;
182 }
183
184 if (!pid) {
185 close(pipefd[1]);
186 if (pipefd[0] != STDIN_FILENO) {
187 if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
Steve Block5ea0c052012-01-06 19:18:11 +0000188 ALOGE("dup2 failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800189 return -1;
190 }
191 close(pipefd[0]);
192 }
San Mehat9d10b342010-01-18 09:51:02 -0800193
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900194 Fwmark fwmark;
195 fwmark.netId = NetworkController::LOCAL_NET_ID;
196 fwmark.explicitlySelected = true;
197 fwmark.protectedFromVpn = true;
198 fwmark.permission = PERMISSION_SYSTEM;
199 char markStr[UINT32_HEX_STRLEN];
200 snprintf(markStr, sizeof(markStr), "0x%x", fwmark.intValue);
201
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800202 int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1;
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700203 char **args = (char **)malloc(sizeof(char *) * num_processed_args);
204 args[num_processed_args - 1] = NULL;
205 args[0] = (char *)"/system/bin/dnsmasq";
Peter Nilssonb756f692011-09-08 09:48:31 -0700206 args[1] = (char *)"--keep-in-foreground";
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700207 args[2] = (char *)"--no-resolv";
208 args[3] = (char *)"--no-poll";
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800209 args[4] = (char *)"--dhcp-authoritative";
Jeff Sharkey6df79da2012-04-18 21:53:35 -0700210 // TODO: pipe through metered status from ConnService
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800211 args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
212 args[6] = (char *)"--pid-file";
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900213 args[7] = (char *)"--listen-mark";
214 args[8] = (char *)markStr;
215 args[9] = (char *)"";
San Mehat9d10b342010-01-18 09:51:02 -0800216
Dmitry Shmidtbc775ed2013-12-12 16:41:16 -0800217 int nextArg = TETHER_START_CONST_ARG;
Erik Kline13fa01f2015-11-12 17:49:23 +0900218 for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
219 asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h",
220 dhcp_ranges[addrIndex], dhcp_ranges[addrIndex+1]);
Robert Greenwalt3208ea02010-03-24 16:32:55 -0700221 }
222
223 if (execv(args[0], args)) {
Steve Block5ea0c052012-01-06 19:18:11 +0000224 ALOGE("execl failed (%s)", strerror(errno));
San Mehat9d10b342010-01-18 09:51:02 -0800225 }
Steve Block5ea0c052012-01-06 19:18:11 +0000226 ALOGE("Should never get here!");
JP Abgrallce4f3792012-08-06 13:44:44 -0700227 _exit(-1);
San Mehat9d10b342010-01-18 09:51:02 -0800228 } else {
229 close(pipefd[0]);
230 mDaemonPid = pid;
231 mDaemonFd = pipefd[1];
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800232 applyDnsInterfaces();
Steve Block7b984e32011-12-20 16:22:42 +0000233 ALOGD("Tethering services running");
San Mehat9d10b342010-01-18 09:51:02 -0800234 }
235
236 return 0;
237}
238
239int TetherController::stopTethering() {
240
241 if (mDaemonPid == 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000242 ALOGE("Tethering already stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800243 return 0;
244 }
245
Steve Block7b984e32011-12-20 16:22:42 +0000246 ALOGD("Stopping tethering services");
San Mehat9d10b342010-01-18 09:51:02 -0800247
248 kill(mDaemonPid, SIGTERM);
San Mehat18737842010-01-21 09:22:43 -0800249 waitpid(mDaemonPid, NULL, 0);
San Mehat9d10b342010-01-18 09:51:02 -0800250 mDaemonPid = 0;
251 close(mDaemonFd);
252 mDaemonFd = -1;
Steve Block7b984e32011-12-20 16:22:42 +0000253 ALOGD("Tethering services stopped");
San Mehat9d10b342010-01-18 09:51:02 -0800254 return 0;
255}
Matthew Xie19944102012-07-12 16:42:07 -0700256
San Mehat9d10b342010-01-18 09:51:02 -0800257bool TetherController::isTetheringStarted() {
258 return (mDaemonPid == 0 ? false : true);
259}
260
Kenny Rootcf52faf2010-02-18 09:59:55 -0800261#define MAX_CMD_SIZE 1024
262
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700263int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
San Mehat9d10b342010-01-18 09:51:02 -0800264 int i;
Kenny Rootcf52faf2010-02-18 09:59:55 -0800265 char daemonCmd[MAX_CMD_SIZE];
San Mehat9d10b342010-01-18 09:51:02 -0800266
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700267 Fwmark fwmark;
268 fwmark.netId = netId;
269 fwmark.explicitlySelected = true;
270 fwmark.protectedFromVpn = true;
271 fwmark.permission = PERMISSION_SYSTEM;
272
Erik Kline13fa01f2015-11-12 17:49:23 +0900273 snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue);
Kenny Rootcf52faf2010-02-18 09:59:55 -0800274 int cmdLen = strlen(daemonCmd);
San Mehat9d10b342010-01-18 09:51:02 -0800275
Erik Kline1d065ba2016-06-08 13:24:45 +0900276 mDnsForwarders.clear();
San Mehat9d10b342010-01-18 09:51:02 -0800277 for (i = 0; i < numServers; i++) {
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700278 ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800279
Lorenzo Colittic2841282015-11-25 22:13:57 +0900280 addrinfo *res, hints = { .ai_flags = AI_NUMERICHOST };
281 int ret = getaddrinfo(servers[i], NULL, &hints, &res);
282 freeaddrinfo(res);
283 if (ret) {
Steve Block5ea0c052012-01-06 19:18:11 +0000284 ALOGE("Failed to parse DNS server '%s'", servers[i]);
Erik Kline1d065ba2016-06-08 13:24:45 +0900285 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900286 errno = EINVAL;
San Mehat9d10b342010-01-18 09:51:02 -0800287 return -1;
288 }
Kenny Rootcf52faf2010-02-18 09:59:55 -0800289
Nick Kralevichad5b41f2012-07-19 18:48:05 -0700290 cmdLen += (strlen(servers[i]) + 1);
291 if (cmdLen + 1 >= MAX_CMD_SIZE) {
Steve Block7b984e32011-12-20 16:22:42 +0000292 ALOGD("Too many DNS servers listed");
Kenny Rootcf52faf2010-02-18 09:59:55 -0800293 break;
294 }
295
Erik Kline13fa01f2015-11-12 17:49:23 +0900296 strcat(daemonCmd, SEPARATOR);
San Mehat9d10b342010-01-18 09:51:02 -0800297 strcat(daemonCmd, servers[i]);
Erik Kline1d065ba2016-06-08 13:24:45 +0900298 mDnsForwarders.push_back(servers[i]);
San Mehat9d10b342010-01-18 09:51:02 -0800299 }
300
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700301 mDnsNetId = netId;
San Mehat9d10b342010-01-18 09:51:02 -0800302 if (mDaemonFd != -1) {
Steve Block7b984e32011-12-20 16:22:42 +0000303 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
San Mehat9d10b342010-01-18 09:51:02 -0800304 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
Steve Block5ea0c052012-01-06 19:18:11 +0000305 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
Erik Kline1d065ba2016-06-08 13:24:45 +0900306 mDnsForwarders.clear();
Lorenzo Colittic2841282015-11-25 22:13:57 +0900307 errno = EREMOTEIO;
San Mehat9d10b342010-01-18 09:51:02 -0800308 return -1;
309 }
310 }
311 return 0;
312}
313
Lorenzo Colitti667c4772014-08-26 14:13:07 -0700314unsigned TetherController::getDnsNetId() {
315 return mDnsNetId;
316}
317
Erik Kline1d065ba2016-06-08 13:24:45 +0900318const std::list<std::string> &TetherController::getDnsForwarders() const {
San Mehat9d10b342010-01-18 09:51:02 -0800319 return mDnsForwarders;
320}
321
Erik Kline1d065ba2016-06-08 13:24:45 +0900322bool TetherController::applyDnsInterfaces() {
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800323 char daemonCmd[MAX_CMD_SIZE];
324
325 strcpy(daemonCmd, "update_ifaces");
326 int cmdLen = strlen(daemonCmd);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800327 bool haveInterfaces = false;
328
Erik Kline1d065ba2016-06-08 13:24:45 +0900329 for (const auto &ifname : mInterfaces) {
330 cmdLen += (ifname.size() + 1);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800331 if (cmdLen + 1 >= MAX_CMD_SIZE) {
332 ALOGD("Too many DNS ifaces listed");
333 break;
334 }
335
Erik Kline13fa01f2015-11-12 17:49:23 +0900336 strcat(daemonCmd, SEPARATOR);
Erik Kline1d065ba2016-06-08 13:24:45 +0900337 strcat(daemonCmd, ifname.c_str());
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800338 haveInterfaces = true;
339 }
340
341 if ((mDaemonFd != -1) && haveInterfaces) {
342 ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
343 if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
344 ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
Erik Kline1d065ba2016-06-08 13:24:45 +0900345 return false;
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800346 }
347 }
Erik Kline1d065ba2016-06-08 13:24:45 +0900348 return true;
San Mehat9d10b342010-01-18 09:51:02 -0800349}
350
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800351int TetherController::tetherInterface(const char *interface) {
352 ALOGD("tetherInterface(%s)", interface);
JP Abgrall69261cb2014-06-19 18:35:24 -0700353 if (!isIfaceName(interface)) {
354 errno = ENOENT;
355 return -1;
356 }
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800357
Erik Kline1d065ba2016-06-08 13:24:45 +0900358 if (!configureForIPv6Router(interface)) {
359 configureForIPv6Client(interface);
360 return -1;
361 }
362 mInterfaces.push_back(interface);
363
364 if (!applyDnsInterfaces()) {
365 mInterfaces.pop_back();
366 configureForIPv6Client(interface);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800367 return -1;
368 } else {
369 return 0;
370 }
371}
372
San Mehat9d10b342010-01-18 09:51:02 -0800373int TetherController::untetherInterface(const char *interface) {
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800374 ALOGD("untetherInterface(%s)", interface);
375
Erik Kline1d065ba2016-06-08 13:24:45 +0900376 for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
377 if (!strcmp(interface, it->c_str())) {
378 mInterfaces.erase(it);
Robert Greenwalt3d4c7582012-12-11 12:33:37 -0800379
Erik Kline1d065ba2016-06-08 13:24:45 +0900380 configureForIPv6Client(interface);
381 return applyDnsInterfaces() ? 0 : -1;
San Mehat9d10b342010-01-18 09:51:02 -0800382 }
383 }
384 errno = ENOENT;
385 return -1;
386}
387
Erik Kline1d065ba2016-06-08 13:24:45 +0900388const std::list<std::string> &TetherController::getTetheredInterfaceList() const {
San Mehat9d10b342010-01-18 09:51:02 -0800389 return mInterfaces;
390}
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900391
Lorenzo Colittia93126d2017-08-24 13:28:19 +0900392int TetherController::setupIptablesHooks() {
393 int res;
394 res = setDefaults();
395 if (res < 0) {
396 return res;
397 }
398
399 // Used to limit downstream mss to the upstream pmtu so we don't end up fragmenting every large
400 // packet tethered devices send. This is IPv4-only, because in IPv6 we send the MTU in the RA.
401 // This is no longer optional and tethering will fail to start if it fails.
402 std::string mssRewriteCommand = StringPrintf(
403 "*mangle\n"
404 "-A %s -p tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu\n"
405 "COMMIT\n", LOCAL_MANGLE_FORWARD);
406
407 // This is for tethering counters. This chain is reached via --goto, and then RETURNS.
408 std::string defaultCommands = StringPrintf(
409 "*filter\n"
410 ":%s -\n"
411 "COMMIT\n", LOCAL_TETHER_COUNTERS_CHAIN);
412
413 res = iptablesRestoreFunction(V4, mssRewriteCommand, nullptr);
414 if (res < 0) {
415 return res;
416 }
417
418 res = iptablesRestoreFunction(V4V6, defaultCommands, nullptr);
419 if (res < 0) {
420 return res;
421 }
422
423 ifacePairList.clear();
424
425 return 0;
426}
427
428int TetherController::setDefaults() {
429 std::string v4Cmd = StringPrintf(
430 "*filter\n"
431 ":%s -\n"
432 "-A %s -j DROP\n"
433 "COMMIT\n"
434 "*nat\n"
435 ":%s -\n"
436 "COMMIT\n", LOCAL_FORWARD, LOCAL_FORWARD, LOCAL_NAT_POSTROUTING);
437
438 std::string v6Cmd = StringPrintf(
439 "*filter\n"
440 ":%s -\n"
441 "COMMIT\n"
442 "*raw\n"
443 ":%s -\n"
444 "COMMIT\n", LOCAL_FORWARD, LOCAL_RAW_PREROUTING);
445
446 int res = iptablesRestoreFunction(V4, v4Cmd, nullptr);
447 if (res < 0) {
448 return res;
449 }
450
451 res = iptablesRestoreFunction(V6, v6Cmd, nullptr);
452 if (res < 0) {
453 return res;
454 }
455
456 natCount = 0;
457
458 return 0;
459}
460
461int TetherController::enableNat(const char* intIface, const char* extIface) {
462 ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
463
464 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
465 errno = ENODEV;
466 return -1;
467 }
468
469 /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */
470 if (!strcmp(intIface, extIface)) {
471 ALOGE("Duplicate interface specified: %s %s", intIface, extIface);
472 errno = EINVAL;
473 return -1;
474 }
475
476 // add this if we are the first added nat
477 if (natCount == 0) {
478 std::vector<std::string> v4Cmds = {
479 "*nat",
480 StringPrintf("-A %s -o %s -j MASQUERADE", LOCAL_NAT_POSTROUTING, extIface),
481 "COMMIT\n"
482 };
483
484 /*
485 * IPv6 tethering doesn't need the state-based conntrack rules, so
486 * it unconditionally jumps to the tether counters chain all the time.
487 */
488 std::vector<std::string> v6Cmds = {
489 "*filter",
490 StringPrintf("-A %s -g %s", LOCAL_FORWARD, LOCAL_TETHER_COUNTERS_CHAIN),
491 "COMMIT\n"
492 };
493
494 if (iptablesRestoreFunction(V4, Join(v4Cmds, '\n'), nullptr) ||
495 iptablesRestoreFunction(V6, Join(v6Cmds, '\n'), nullptr)) {
496 ALOGE("Error setting postroute rule: iface=%s", extIface);
497 // unwind what's been done, but don't care about success - what more could we do?
498 setDefaults();
499 return -1;
500 }
501 }
502
503 if (setForwardRules(true, intIface, extIface) != 0) {
504 ALOGE("Error setting forward rules");
505 if (natCount == 0) {
506 setDefaults();
507 }
508 errno = ENODEV;
509 return -1;
510 }
511
512 natCount++;
513 return 0;
514}
515
516bool TetherController::checkTetherCountingRuleExist(const std::string& pair_name) {
517 return std::find(ifacePairList.begin(), ifacePairList.end(), pair_name) != ifacePairList.end();
518}
519
520/* static */
521std::string TetherController::makeTetherCountingRule(const char *if1, const char *if2) {
522 return StringPrintf("-A %s -i %s -o %s -j RETURN", LOCAL_TETHER_COUNTERS_CHAIN, if1, if2);
523}
524
525int TetherController::setForwardRules(bool add, const char *intIface, const char *extIface) {
526 const char *op = add ? "-A" : "-D";
527
528 std::string rpfilterCmd = StringPrintf(
529 "*raw\n"
530 "%s %s -i %s -m rpfilter --invert ! -s fe80::/64 -j DROP\n"
531 "COMMIT\n", op, LOCAL_RAW_PREROUTING, intIface);
532 if (iptablesRestoreFunction(V6, rpfilterCmd, nullptr) == -1 && add) {
533 return -1;
534 }
535
536 std::vector<std::string> v4 = {
537 "*filter",
538 StringPrintf("%s %s -i %s -o %s -m state --state ESTABLISHED,RELATED -g %s",
539 op, LOCAL_FORWARD, extIface, intIface, LOCAL_TETHER_COUNTERS_CHAIN),
540 StringPrintf("%s %s -i %s -o %s -m state --state INVALID -j DROP",
541 op, LOCAL_FORWARD, intIface, extIface),
542 StringPrintf("%s %s -i %s -o %s -g %s",
543 op, LOCAL_FORWARD, intIface, extIface, LOCAL_TETHER_COUNTERS_CHAIN),
544 };
545
546 std::vector<std::string> v6 = {
547 "*filter",
548 };
549
550 /* We only ever add tethering quota rules so that they stick. */
551 std::string pair1 = StringPrintf("%s_%s", intIface, extIface);
552 if (add && !checkTetherCountingRuleExist(pair1)) {
553 v4.push_back(makeTetherCountingRule(intIface, extIface));
554 v6.push_back(makeTetherCountingRule(intIface, extIface));
555 }
556 std::string pair2 = StringPrintf("%s_%s", extIface, intIface);
557 if (add && !checkTetherCountingRuleExist(pair2)) {
558 v4.push_back(makeTetherCountingRule(extIface, intIface));
559 v6.push_back(makeTetherCountingRule(extIface, intIface));
560 }
561
562 // Always make sure the drop rule is at the end.
563 // TODO: instead of doing this, consider just rebuilding LOCAL_FORWARD completely from scratch
564 // every time, starting with ":natctrl_FORWARD -\n". This method would likely be a bit simpler.
565 if (add) {
566 v4.push_back(StringPrintf("-D %s -j DROP", LOCAL_FORWARD));
567 v4.push_back(StringPrintf("-A %s -j DROP", LOCAL_FORWARD));
568 }
569
570 v4.push_back("COMMIT\n");
571 v6.push_back("COMMIT\n");
572
573 // We only add IPv6 rules here, never remove them.
574 if (iptablesRestoreFunction(V4, Join(v4, '\n'), nullptr) == -1 ||
575 (add && iptablesRestoreFunction(V6, Join(v6, '\n'), nullptr) == -1)) {
576 // unwind what's been done, but don't care about success - what more could we do?
577 if (add) {
578 setForwardRules(false, intIface, extIface);
579 }
580 return -1;
581 }
582
583 if (add && !checkTetherCountingRuleExist(pair1)) {
584 ifacePairList.push_front(pair1);
585 }
586 if (add && !checkTetherCountingRuleExist(pair2)) {
587 ifacePairList.push_front(pair2);
588 }
589
590 return 0;
591}
592
593int TetherController::disableNat(const char* intIface, const char* extIface) {
594 if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
595 errno = ENODEV;
596 return -1;
597 }
598
599 setForwardRules(false, intIface, extIface);
600 if (--natCount <= 0) {
601 // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
602 setDefaults();
603 }
604 return 0;
605}
606
607void TetherController::addStats(TetherStatsList& statsList, const TetherStats& stats) {
608 for (TetherStats& existing : statsList) {
609 if (existing.addStatsIfMatch(stats)) {
610 return;
611 }
612 }
613 // No match. Insert a new interface pair.
614 statsList.push_back(stats);
615}
616
617/*
618 * Parse the ptks and bytes out of:
619 * Chain natctrl_tether_counters (4 references)
620 * pkts bytes target prot opt in out source destination
621 * 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
622 * 27 2002 RETURN all -- rmnet0 wlan0 0.0.0.0/0 0.0.0.0/0
623 * 1040 107471 RETURN all -- bt-pan rmnet0 0.0.0.0/0 0.0.0.0/0
624 * 1450 1708806 RETURN all -- rmnet0 bt-pan 0.0.0.0/0 0.0.0.0/0
625 * or:
626 * Chain natctrl_tether_counters (0 references)
627 * pkts bytes target prot opt in out source destination
628 * 0 0 RETURN all wlan0 rmnet_data0 ::/0 ::/0
629 * 0 0 RETURN all rmnet_data0 wlan0 ::/0 ::/0
630 *
631 * It results in an error if invoked and no tethering counter rules exist. The constraint
632 * helps detect complete parsing failure.
633 */
634int TetherController::addForwardChainStats(const TetherStats& filter,
635 TetherStatsList& statsList,
636 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;
645 const char *buffPtr;
646 int64_t packets, bytes;
647 int statsFound = 0;
648
649 bool filterPair = filter.intIface[0] && filter.extIface[0];
650
651 ALOGV("filter: %s", filter.getStatsLine().c_str());
652
653 stats = filter;
654
655 std::stringstream stream(statsOutput);
656 while (std::getline(stream, statsLine, '\n')) {
657 buffPtr = statsLine.c_str();
658
659 /* Clean up, so a failed parse can still print info */
660 iface0[0] = iface1[0] = rest[0] = packets = bytes = 0;
661 if (strstr(buffPtr, "0.0.0.0")) {
662 // IPv4 has -- indicating what to do with fragments...
663 // 26 2373 RETURN all -- wlan0 rmnet0 0.0.0.0/0 0.0.0.0/0
664 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all -- %s %s 0.%s",
665 &packets, &bytes, iface0, iface1, rest);
666 } else {
667 // ... but IPv6 does not.
668 // 26 2373 RETURN all wlan0 rmnet0 ::/0 ::/0
669 res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all %s %s ::/%s",
670 &packets, &bytes, iface0, iface1, rest);
671 }
672 ALOGV("parse res=%d iface0=<%s> iface1=<%s> pkts=%" PRId64" bytes=%" PRId64" rest=<%s> orig line=<%s>", res,
673 iface0, iface1, packets, bytes, rest, buffPtr);
674 extraProcessingInfo += buffPtr;
675 extraProcessingInfo += "\n";
676
677 if (res != 5) {
678 continue;
679 }
680 /*
681 * The following assumes that the 1st rule has in:extIface out:intIface,
682 * which is what TetherController sets up.
683 * If not filtering, the 1st match rx, and sets up the pair for the tx side.
684 */
685 if (filter.intIface[0] && filter.extIface[0]) {
686 if (filter.intIface == iface0 && filter.extIface == iface1) {
687 ALOGV("2Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
688 stats.rxPackets = packets;
689 stats.rxBytes = bytes;
690 } else if (filter.intIface == iface1 && filter.extIface == iface0) {
691 ALOGV("2Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
692 stats.txPackets = packets;
693 stats.txBytes = bytes;
694 }
695 } else if (filter.intIface[0] || filter.extIface[0]) {
696 if (filter.intIface == iface0 || filter.extIface == iface1) {
697 ALOGV("1Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
698 stats.intIface = iface0;
699 stats.extIface = iface1;
700 stats.rxPackets = packets;
701 stats.rxBytes = bytes;
702 } else if (filter.intIface == iface1 || filter.extIface == iface0) {
703 ALOGV("1Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
704 stats.intIface = iface1;
705 stats.extIface = iface0;
706 stats.txPackets = packets;
707 stats.txBytes = bytes;
708 }
709 } else /* if (!filter.intFace[0] && !filter.extIface[0]) */ {
710 if (!stats.intIface[0]) {
711 ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
712 stats.intIface = iface0;
713 stats.extIface = iface1;
714 stats.rxPackets = packets;
715 stats.rxBytes = bytes;
716 } else if (stats.intIface == iface1 && stats.extIface == iface0) {
717 ALOGV("0Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
718 stats.txPackets = packets;
719 stats.txBytes = bytes;
720 }
721 }
722 if (stats.rxBytes != -1 && stats.txBytes != -1) {
723 ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64" filterPair=%d", stats.rxBytes, stats.txBytes, filterPair);
724 addStats(statsList, stats);
725 if (filterPair) {
726 return 0;
727 } else {
728 statsFound++;
729 stats = filter;
730 }
731 }
732 }
733
734 /* It is always an error to find only one side of the stats. */
735 /* It is an error to find nothing when not filtering. */
736 if (((stats.rxBytes == -1) != (stats.txBytes == -1)) ||
737 (!statsFound && !filterPair)) {
738 return -1;
739 }
740 return 0;
741}
742
743std::string TetherController::TetherStats::getStatsLine() const {
744 std::string msg;
745 StringAppendF(&msg, "%s %s %" PRId64" %" PRId64" %" PRId64" %" PRId64, intIface.c_str(),
746 extIface.c_str(), rxBytes, rxPackets, txBytes, txPackets);
747 return msg;
748}
749
750int TetherController::getTetherStats(SocketClient *cli, TetherStats& filter,
751 std::string &extraProcessingInfo) {
752 int res = 0;
753
754 TetherStatsList statsList;
755
756 for (const IptablesTarget target : {V4, V6}) {
757 std::string statsString;
758 res = iptablesRestoreFunction(target, GET_TETHER_STATS_COMMAND, &statsString);
759 if (res != 0) {
760 ALOGE("Failed to run %s err=%d", GET_TETHER_STATS_COMMAND.c_str(), res);
761 return -1;
762 }
763
764 res = addForwardChainStats(filter, statsList, statsString, extraProcessingInfo);
765 if (res != 0) {
766 return res;
767 }
768 }
769
770 if (filter.intIface[0] && filter.extIface[0] && statsList.size() == 1) {
771 cli->sendMsg(ResponseCode::TetheringStatsResult,
772 statsList[0].getStatsLine().c_str(), false);
773 } else {
774 for (const auto& stats: statsList) {
775 cli->sendMsg(ResponseCode::TetheringStatsListResult,
776 stats.getStatsLine().c_str(), false);
777 }
778 if (res == 0) {
779 cli->sendMsg(ResponseCode::CommandOkay, "Tethering stats list completed", false);
780 }
781 }
782
783 return res;
784}
785
Lorenzo Colittie20a5262017-05-09 18:30:44 +0900786} // namespace net
787} // namespace android