blob: 1e993c1bc247c4cbcf52a139dc5e5518ac40f62d [file] [log] [blame]
Lorenzo Colittie4d626e2016-02-02 17:19:04 +09001/**
2 * Copyright (c) 2016, 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
17#define LOG_TAG "Netd"
18
Luke Huangcaebcbb2018-09-27 20:37:14 +080019#include <cinttypes>
Ben Schwartz4204ecf2017-10-02 12:35:48 -040020#include <set>
Erik Kline38e51f12018-09-06 20:14:44 +090021#include <tuple>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090022#include <vector>
23
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090024#include <android-base/stringprintf.h>
Ben Schwartz4204ecf2017-10-02 12:35:48 -040025#include <android-base/strings.h>
Robin Lee2cf56172016-09-13 18:55:42 +090026#include <cutils/properties.h>
Logan Chien3f461482018-04-23 14:31:32 +080027#include <log/log.h>
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090028#include <utils/Errors.h>
Pierre Imaibeedec32016-04-13 06:44:51 +090029#include <utils/String16.h>
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090030
31#include <binder/IPCThreadState.h>
32#include <binder/IServiceManager.h>
33#include "android/net/BnNetd.h"
34
Ben Schwartze7601812017-04-28 16:38:29 -040035#include <openssl/base64.h>
36
Lorenzo Colitti89faa342016-02-26 11:38:47 +090037#include "Controllers.h"
Erik Kline2d3a1632016-03-15 16:33:48 +090038#include "DumpWriter.h"
Michal Karpinskid5440112016-10-06 16:56:04 +010039#include "EventReporter.h"
Erik Kline55b06f82016-07-04 09:57:18 +090040#include "InterfaceController.h"
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090041#include "NetdConstants.h"
42#include "NetdNativeService.h"
Luke Huangb670d162018-08-23 20:01:13 +080043#include "Permission.h"
Erik Kline85890042018-05-25 19:19:11 +090044#include "Process.h"
Robin Leeb8087362016-03-30 18:43:08 +010045#include "RouteController.h"
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090046#include "SockDiag.h"
Robin Leeb8087362016-03-30 18:43:08 +010047#include "UidRanges.h"
Bernie Innocenti189eb502018-10-01 23:10:18 +090048#include "netid_client.h" // NETID_UNSET
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090049
50using android::base::StringPrintf;
Luke Huangcaebcbb2018-09-27 20:37:14 +080051using android::net::TetherStatsParcel;
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090052
53namespace android {
54namespace net {
55
56namespace {
57
58const char CONNECTIVITY_INTERNAL[] = "android.permission.CONNECTIVITY_INTERNAL";
Joel Scherpelz08b84cd2017-05-22 13:11:54 +090059const char NETWORK_STACK[] = "android.permission.NETWORK_STACK";
Erik Kline2d3a1632016-03-15 16:33:48 +090060const char DUMP[] = "android.permission.DUMP";
Erik Klineb31fd692018-06-06 20:50:11 +090061const char OPT_SHORT[] = "--short";
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090062
63binder::Status checkPermission(const char *permission) {
Luke Huanga38b65c2018-09-26 16:31:03 +080064 pid_t pid = IPCThreadState::self()->getCallingPid();
65 uid_t uid = IPCThreadState::self()->getCallingUid();
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090066
Luke Huanga38b65c2018-09-26 16:31:03 +080067 // If the caller is the system UID, don't check permissions.
68 // Otherwise, if the system server's binder thread pool is full, and all the threads are
69 // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
70 //
71 // From a security perspective, there is currently no difference, because:
72 // 1. The only permissions we check in netd's binder interface are CONNECTIVITY_INTERNAL
73 // and NETWORK_STACK, which the system server will always need to have.
74 // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
75 if (uid == AID_SYSTEM || checkPermission(String16(permission), pid, uid)) {
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090076 return binder::Status::ok();
77 } else {
78 auto err = StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission);
79 return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(err.c_str()));
80 }
81}
82
Robin Lee2cf56172016-09-13 18:55:42 +090083#define ENFORCE_DEBUGGABLE() { \
84 char value[PROPERTY_VALUE_MAX + 1]; \
Yi Kongbdfd57e2018-07-25 13:26:10 -070085 if (property_get("ro.debuggable", value, nullptr) != 1 \
Robin Lee2cf56172016-09-13 18:55:42 +090086 || value[0] != '1') { \
87 return binder::Status::fromExceptionCode( \
88 binder::Status::EX_SECURITY, \
89 String8("Not available in production builds.") \
90 ); \
91 } \
92}
93
Lorenzo Colittie4d626e2016-02-02 17:19:04 +090094#define ENFORCE_PERMISSION(permission) { \
95 binder::Status status = checkPermission((permission)); \
96 if (!status.isOk()) { \
97 return status; \
98 } \
99}
100
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900101#define NETD_LOCKING_RPC(permission, lock) \
102 ENFORCE_PERMISSION(permission); \
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900103 std::lock_guard _lock(lock);
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900104
105#define NETD_BIG_LOCK_RPC(permission) NETD_LOCKING_RPC((permission), gBigNetdLock)
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900106
Bernie Innocenti97f388f2018-10-16 19:17:08 +0900107binder::Status asBinderStatus(const netdutils::Status& status) {
108 if (isOk(status)) {
109 return binder::Status::ok();
110 }
111 return binder::Status::fromServiceSpecificError(status.code(), status.msg().c_str());
112}
113
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900114inline binder::Status statusFromErrcode(int ret) {
115 if (ret) {
116 return binder::Status::fromServiceSpecificError(-ret, strerror(-ret));
117 }
118 return binder::Status::ok();
119}
120
Erik Klineb31fd692018-06-06 20:50:11 +0900121bool contains(const Vector<String16>& words, const String16& word) {
122 for (const auto& w : words) {
123 if (w == word) return true;
124 }
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900125
Erik Klineb31fd692018-06-06 20:50:11 +0900126 return false;
127}
128
129} // namespace
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900130
Lorenzo Colittie4851de2016-03-17 13:23:28 +0900131status_t NetdNativeService::start() {
132 IPCThreadState::self()->disableBackgroundScheduling(true);
Erik Klineb31fd692018-06-06 20:50:11 +0900133 const status_t ret = BinderService<NetdNativeService>::publish();
Lorenzo Colittie4851de2016-03-17 13:23:28 +0900134 if (ret != android::OK) {
135 return ret;
136 }
137 sp<ProcessState> ps(ProcessState::self());
138 ps->startThreadPool();
139 ps->giveThreadPoolName();
140 return android::OK;
141}
142
Hugo Benichi7b314e12018-01-15 21:54:00 +0900143status_t NetdNativeService::dump(int fd, const Vector<String16> &args) {
Erik Kline2d3a1632016-03-15 16:33:48 +0900144 const binder::Status dump_permission = checkPermission(DUMP);
145 if (!dump_permission.isOk()) {
146 const String8 msg(dump_permission.toString8());
147 write(fd, msg.string(), msg.size());
148 return PERMISSION_DENIED;
149 }
150
151 // This method does not grab any locks. If individual classes need locking
152 // their dump() methods MUST handle locking appropriately.
Hugo Benichi7b314e12018-01-15 21:54:00 +0900153
Erik Kline2d3a1632016-03-15 16:33:48 +0900154 DumpWriter dw(fd);
Hugo Benichi7b314e12018-01-15 21:54:00 +0900155
156 if (!args.isEmpty() && args[0] == TcpSocketMonitor::DUMP_KEYWORD) {
157 dw.blankline();
158 gCtls->tcpSocketMonitor.dump(dw);
159 dw.blankline();
160 return NO_ERROR;
161 }
162
Chenbo Fengef297172018-03-26 10:53:33 -0700163 if (!args.isEmpty() && args[0] == TrafficController::DUMP_KEYWORD) {
164 dw.blankline();
165 gCtls->trafficCtrl.dump(dw, true);
166 dw.blankline();
167 return NO_ERROR;
168 }
169
Erik Kline85890042018-05-25 19:19:11 +0900170 process::dump(dw);
Erik Kline2d3a1632016-03-15 16:33:48 +0900171 dw.blankline();
172 gCtls->netCtrl.dump(dw);
173 dw.blankline();
174
Chenbo Fengef297172018-03-26 10:53:33 -0700175 gCtls->trafficCtrl.dump(dw, false);
176 dw.blankline();
177
Erik Klineb31fd692018-06-06 20:50:11 +0900178 {
179 ScopedIndent indentLog(dw);
180 if (contains(args, String16(OPT_SHORT))) {
181 dw.println("Log: <omitted>");
182 } else {
183 dw.println("Log:");
184 ScopedIndent indentLogEntries(dw);
185 gLog.forEachEntry([&dw](const std::string& entry) mutable { dw.println(entry); });
186 }
187 dw.blankline();
188 }
189
Erik Kline2d3a1632016-03-15 16:33:48 +0900190 return NO_ERROR;
191}
192
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900193binder::Status NetdNativeService::isAlive(bool *alive) {
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900194 NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900195 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900196
197 *alive = true;
Erik Klineb31fd692018-06-06 20:50:11 +0900198
199 gLog.log(entry.returns(*alive));
Lorenzo Colittie4d626e2016-02-02 17:19:04 +0900200 return binder::Status::ok();
201}
202
Erik Klinef52d4522018-03-14 15:01:46 +0900203binder::Status NetdNativeService::firewallReplaceUidChain(const std::string& chainName,
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900204 bool isWhitelist, const std::vector<int32_t>& uids, bool *ret) {
205 NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->firewallCtrl.lock);
Erik Klineb31fd692018-06-06 20:50:11 +0900206 auto entry = gLog.newEntry()
207 .prettyFunction(__PRETTY_FUNCTION__)
208 .arg(chainName)
209 .arg(isWhitelist)
210 .arg(uids);
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900211
Erik Klinef52d4522018-03-14 15:01:46 +0900212 int err = gCtls->firewallCtrl.replaceUidChain(chainName, isWhitelist, uids);
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900213 *ret = (err == 0);
Erik Klineb31fd692018-06-06 20:50:11 +0900214
215 gLog.log(entry.returns(*ret).withAutomaticDuration());
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900216 return binder::Status::ok();
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900217}
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900218
219binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) {
220 NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->bandwidthCtrl.lock);
Erik Klineb31fd692018-06-06 20:50:11 +0900221 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(enable);
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900222
223 int err = gCtls->bandwidthCtrl.enableDataSaver(enable);
224 *ret = (err == 0);
Erik Klineb31fd692018-06-06 20:50:11 +0900225 gLog.log(entry.returns(*ret).withAutomaticDuration());
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900226 return binder::Status::ok();
227}
228
Luke Huang531f5d32018-08-03 15:19:05 +0800229binder::Status NetdNativeService::bandwidthSetInterfaceQuota(const std::string& ifName,
230 int64_t bytes) {
231 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
232 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName).arg(bytes);
233
234 int res = gCtls->bandwidthCtrl.setInterfaceQuota(ifName, bytes);
235
236 gLog.log(entry.returns(res).withAutomaticDuration());
237 return statusFromErrcode(res);
238}
239
240binder::Status NetdNativeService::bandwidthRemoveInterfaceQuota(const std::string& ifName) {
241 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
242 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
243
244 int res = gCtls->bandwidthCtrl.removeInterfaceQuota(ifName);
245
246 gLog.log(entry.returns(res).withAutomaticDuration());
247 return statusFromErrcode(res);
248}
249
250binder::Status NetdNativeService::bandwidthSetInterfaceAlert(const std::string& ifName,
251 int64_t bytes) {
252 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
253 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName).arg(bytes);
254
255 int res = gCtls->bandwidthCtrl.setInterfaceAlert(ifName, bytes);
256
257 gLog.log(entry.returns(res).withAutomaticDuration());
258 return statusFromErrcode(res);
259}
260
261binder::Status NetdNativeService::bandwidthRemoveInterfaceAlert(const std::string& ifName) {
262 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
263 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
264
265 int res = gCtls->bandwidthCtrl.removeInterfaceAlert(ifName);
266
267 gLog.log(entry.returns(res).withAutomaticDuration());
268 return statusFromErrcode(res);
269}
270
271binder::Status NetdNativeService::bandwidthSetGlobalAlert(int64_t bytes) {
272 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
273 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(bytes);
274
275 int res = gCtls->bandwidthCtrl.setGlobalAlert(bytes);
276
277 gLog.log(entry.returns(res).withAutomaticDuration());
278 return statusFromErrcode(res);
279}
280
281binder::Status NetdNativeService::bandwidthAddNaughtyApp(int32_t uid) {
282 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
283 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
284
285 std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
286 int res = gCtls->bandwidthCtrl.addNaughtyApps(appStrUids);
287
288 gLog.log(entry.returns(res).withAutomaticDuration());
289 return statusFromErrcode(res);
290}
291
292binder::Status NetdNativeService::bandwidthRemoveNaughtyApp(int32_t uid) {
293 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
294 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
295
296 std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
297 int res = gCtls->bandwidthCtrl.removeNaughtyApps(appStrUids);
298
299 gLog.log(entry.returns(res).withAutomaticDuration());
300 return statusFromErrcode(res);
301}
302
303binder::Status NetdNativeService::bandwidthAddNiceApp(int32_t uid) {
304 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
305 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
306
307 std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
308 int res = gCtls->bandwidthCtrl.addNiceApps(appStrUids);
309
310 gLog.log(entry.returns(res).withAutomaticDuration());
311 return statusFromErrcode(res);
312}
313
314binder::Status NetdNativeService::bandwidthRemoveNiceApp(int32_t uid) {
315 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->bandwidthCtrl.lock);
316 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
317
318 std::vector<std::string> appStrUids = {std::to_string(abs(uid))};
319 int res = gCtls->bandwidthCtrl.removeNiceApps(appStrUids);
320
321 gLog.log(entry.returns(res).withAutomaticDuration());
322 return statusFromErrcode(res);
323}
324
Luke Huangb670d162018-08-23 20:01:13 +0800325binder::Status NetdNativeService::networkCreatePhysical(int32_t netId, int32_t permission) {
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900326 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900327 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId).arg(permission);
Luke Huangb670d162018-08-23 20:01:13 +0800328 int ret = gCtls->netCtrl.createPhysicalNetwork(netId, convertPermission(permission));
Erik Klineb31fd692018-06-06 20:50:11 +0900329 gLog.log(entry.returns(ret).withAutomaticDuration());
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900330 return statusFromErrcode(ret);
331}
332
333binder::Status NetdNativeService::networkCreateVpn(int32_t netId, bool hasDns, bool secure) {
334 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
335 int ret = gCtls->netCtrl.createVirtualNetwork(netId, hasDns, secure);
336 return statusFromErrcode(ret);
337}
338
339binder::Status NetdNativeService::networkDestroy(int32_t netId) {
Erik Klinec8b6a9c2018-01-15 17:06:48 +0900340 ENFORCE_PERMISSION(NETWORK_STACK);
341 // Both of these functions manage their own locking internally.
342 const int ret = gCtls->netCtrl.destroyNetwork(netId);
343 gCtls->resolverCtrl.clearDnsServers(netId);
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900344 return statusFromErrcode(ret);
345}
346
347binder::Status NetdNativeService::networkAddInterface(int32_t netId, const std::string& iface) {
348 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
349 int ret = gCtls->netCtrl.addInterfaceToNetwork(netId, iface.c_str());
350 return statusFromErrcode(ret);
351}
352
353binder::Status NetdNativeService::networkRemoveInterface(int32_t netId, const std::string& iface) {
354 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
355 int ret = gCtls->netCtrl.removeInterfaceFromNetwork(netId, iface.c_str());
356 return statusFromErrcode(ret);
357}
358
359binder::Status NetdNativeService::networkAddUidRanges(int32_t netId,
360 const std::vector<UidRange>& uidRangeArray) {
361 // NetworkController::addUsersToNetwork is thread-safe.
362 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
363 int ret = gCtls->netCtrl.addUsersToNetwork(netId, UidRanges(uidRangeArray));
364 return statusFromErrcode(ret);
365}
366
367binder::Status NetdNativeService::networkRemoveUidRanges(int32_t netId,
368 const std::vector<UidRange>& uidRangeArray) {
369 // NetworkController::removeUsersFromNetwork is thread-safe.
370 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
371 int ret = gCtls->netCtrl.removeUsersFromNetwork(netId, UidRanges(uidRangeArray));
372 return statusFromErrcode(ret);
373}
374
Robin Leeb8087362016-03-30 18:43:08 +0100375binder::Status NetdNativeService::networkRejectNonSecureVpn(bool add,
376 const std::vector<UidRange>& uidRangeArray) {
377 // TODO: elsewhere RouteController is only used from the tethering and network controllers, so
378 // it should be possible to use the same lock as NetworkController. However, every call through
379 // the CommandListener "network" command will need to hold this lock too, not just the ones that
380 // read/modify network internal state (that is sufficient for ::dump() because it doesn't
381 // look at routes, but it's not enough here).
382 NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
383
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900384 UidRanges uidRanges(uidRangeArray);
Robin Leeb8087362016-03-30 18:43:08 +0100385
386 int err;
387 if (add) {
388 err = RouteController::addUsersToRejectNonSecureNetworkRule(uidRanges);
389 } else {
390 err = RouteController::removeUsersFromRejectNonSecureNetworkRule(uidRanges);
391 }
392
Lorenzo Colittid33e96d2016-12-15 23:59:01 +0900393 return statusFromErrcode(err);
Robin Leeb8087362016-03-30 18:43:08 +0100394}
395
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900396binder::Status NetdNativeService::socketDestroy(const std::vector<UidRange>& uids,
397 const std::vector<int32_t>& skipUids) {
398
399 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
400
401 SockDiag sd;
402 if (!sd.open()) {
403 return binder::Status::fromServiceSpecificError(EIO,
404 String8("Could not open SOCK_DIAG socket"));
405 }
406
407 UidRanges uidRanges(uids);
Lorenzo Colittie5c3c992016-07-26 17:53:50 +0900408 int err = sd.destroySockets(uidRanges, std::set<uid_t>(skipUids.begin(), skipUids.end()),
409 true /* excludeLoopback */);
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900410
411 if (err) {
412 return binder::Status::fromServiceSpecificError(-err,
413 String8::format("destroySockets: %s", strerror(-err)));
414 }
Pierre Imaibeedec32016-04-13 06:44:51 +0900415 return binder::Status::ok();
416}
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900417
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400418// Parse a base64 encoded string into a vector of bytes.
419// On failure, return an empty vector.
420static std::vector<uint8_t> parseBase64(const std::string& input) {
421 std::vector<uint8_t> decoded;
422 size_t out_len;
423 if (EVP_DecodedLength(&out_len, input.size()) != 1) {
424 return decoded;
425 }
426 // out_len is now an upper bound on the output length.
427 decoded.resize(out_len);
428 if (EVP_DecodeBase64(decoded.data(), &out_len, decoded.size(),
429 reinterpret_cast<const uint8_t*>(input.data()), input.size()) == 1) {
430 // Possibly shrink the vector if the actual output was smaller than the bound.
431 decoded.resize(out_len);
432 } else {
433 decoded.clear();
434 }
435 if (out_len != SHA256_SIZE) {
436 decoded.clear();
437 }
438 return decoded;
439}
440
Pierre Imaibeedec32016-04-13 06:44:51 +0900441binder::Status NetdNativeService::setResolverConfiguration(int32_t netId,
442 const std::vector<std::string>& servers, const std::vector<std::string>& domains,
Erik Klinea1476fb2018-03-04 21:01:56 +0900443 const std::vector<int32_t>& params, const std::string& tlsName,
444 const std::vector<std::string>& tlsServers,
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400445 const std::vector<std::string>& tlsFingerprints) {
Pierre Imaibeedec32016-04-13 06:44:51 +0900446 // This function intentionally does not lock within Netd, as Bionic is thread-safe.
447 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900448 auto entry = gLog.newEntry()
449 .prettyFunction(__PRETTY_FUNCTION__)
450 .arg(netId)
451 .arg(servers)
452 .arg(domains)
453 .arg(params)
454 .arg(tlsName)
455 .arg(tlsServers)
456 .arg(tlsFingerprints);
Pierre Imaibeedec32016-04-13 06:44:51 +0900457
Ben Schwartz4204ecf2017-10-02 12:35:48 -0400458 std::set<std::vector<uint8_t>> decoded_fingerprints;
459 for (const std::string& fingerprint : tlsFingerprints) {
460 std::vector<uint8_t> decoded = parseBase64(fingerprint);
461 if (decoded.empty()) {
462 return binder::Status::fromServiceSpecificError(EINVAL,
463 String8::format("ResolverController error: bad fingerprint"));
464 }
465 decoded_fingerprints.emplace(decoded);
466 }
467
468 int err = gCtls->resolverCtrl.setResolverConfiguration(netId, servers, domains, params,
Erik Klinea1476fb2018-03-04 21:01:56 +0900469 tlsName, tlsServers, decoded_fingerprints);
Erik Klineb31fd692018-06-06 20:50:11 +0900470 gLog.log(entry.returns(err).withAutomaticDuration());
Pierre Imaibeedec32016-04-13 06:44:51 +0900471 if (err != 0) {
472 return binder::Status::fromServiceSpecificError(-err,
473 String8::format("ResolverController error: %s", strerror(-err)));
474 }
475 return binder::Status::ok();
476}
477
478binder::Status NetdNativeService::getResolverInfo(int32_t netId,
479 std::vector<std::string>* servers, std::vector<std::string>* domains,
480 std::vector<int32_t>* params, std::vector<int32_t>* stats) {
481 // This function intentionally does not lock within Netd, as Bionic is thread-safe.
482 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
483
484 int err = gCtls->resolverCtrl.getResolverInfo(netId, servers, domains, params, stats);
485 if (err != 0) {
486 return binder::Status::fromServiceSpecificError(-err,
487 String8::format("ResolverController error: %s", strerror(-err)));
488 }
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900489 return binder::Status::ok();
490}
491
Erik Klinef48e4dd2016-07-18 04:02:07 +0900492binder::Status NetdNativeService::tetherApplyDnsInterfaces(bool *ret) {
Luke Huangd1ee4622018-06-29 13:49:58 +0800493 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
Erik Klinef48e4dd2016-07-18 04:02:07 +0900494
495 *ret = gCtls->tetherCtrl.applyDnsInterfaces();
496 return binder::Status::ok();
497}
498
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900499namespace {
500
Luke Huangcaebcbb2018-09-27 20:37:14 +0800501void tetherAddStatsByInterface(TetherController::TetherStats* tetherStatsParcel,
502 const TetherController::TetherStats& tetherStats) {
503 if (tetherStatsParcel->extIface == tetherStats.extIface) {
504 tetherStatsParcel->rxBytes += tetherStats.rxBytes;
505 tetherStatsParcel->rxPackets += tetherStats.rxPackets;
506 tetherStatsParcel->txBytes += tetherStats.txBytes;
507 tetherStatsParcel->txPackets += tetherStats.txPackets;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900508 }
Luke Huangcaebcbb2018-09-27 20:37:14 +0800509}
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900510
Luke Huangcaebcbb2018-09-27 20:37:14 +0800511TetherStatsParcel toTetherStatsParcel(const TetherController::TetherStats& stats) {
512 TetherStatsParcel result;
513 result.iface = stats.extIface;
514 result.rxBytes = stats.rxBytes;
515 result.rxPackets = stats.rxPackets;
516 result.txBytes = stats.txBytes;
517 result.txPackets = stats.txPackets;
518 return result;
519}
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900520
Luke Huangcaebcbb2018-09-27 20:37:14 +0800521void setTetherStatsParcelVecByInterface(std::vector<TetherStatsParcel>* tetherStatsVec,
522 const TetherController::TetherStatsList& statsList) {
523 std::map<std::string, TetherController::TetherStats> statsMap;
524 for (const auto& stats : statsList) {
525 auto iter = statsMap.find(stats.extIface);
526 if (iter != statsMap.end()) {
527 tetherAddStatsByInterface(&(iter->second), stats);
528 } else {
529 statsMap.insert(
530 std::pair<std::string, TetherController::TetherStats>(stats.extIface, stats));
531 }
532 }
533 for (auto iter = statsMap.begin(); iter != statsMap.end(); iter++) {
534 tetherStatsVec->push_back(toTetherStatsParcel(iter->second));
535 }
536}
537
538std::vector<std::string> tetherStatsParcelVecToStringVec(std::vector<TetherStatsParcel>* tVec) {
539 std::vector<std::string> result;
540 for (const auto& t : *tVec) {
541 result.push_back(StringPrintf("%s:%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64,
542 t.iface.c_str(), t.rxBytes, t.rxPackets, t.txBytes,
543 t.txPackets));
544 }
545 return result;
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900546}
547
548} // namespace
549
Luke Huangcaebcbb2018-09-27 20:37:14 +0800550binder::Status NetdNativeService::tetherGetStats(
551 std::vector<TetherStatsParcel>* tetherStatsParcelVec) {
Luke Huangd1ee4622018-06-29 13:49:58 +0800552 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900553
Luke Huangcaebcbb2018-09-27 20:37:14 +0800554 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
555
Lorenzo Colitti5192bf72017-09-04 13:30:59 +0900556 const auto& statsList = gCtls->tetherCtrl.getTetherStats();
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900557 if (!isOk(statsList)) {
Nathan Harold28ccfef2018-03-16 19:02:47 -0700558 return asBinderStatus(statsList);
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900559 }
Luke Huangcaebcbb2018-09-27 20:37:14 +0800560 setTetherStatsParcelVecByInterface(tetherStatsParcelVec, statsList.value());
561 auto statsResults = tetherStatsParcelVecToStringVec(tetherStatsParcelVec);
562 gLog.log(entry.returns(base::Join(statsResults, ";")).withAutomaticDuration());
Lorenzo Colitti9a8a9ff2017-01-31 19:06:59 +0900563 return binder::Status::ok();
564}
565
Erik Kline53c20882016-08-02 15:22:53 +0900566binder::Status NetdNativeService::interfaceAddAddress(const std::string &ifName,
567 const std::string &addrString, int prefixLength) {
568 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
569
570 const int err = InterfaceController::addAddress(
571 ifName.c_str(), addrString.c_str(), prefixLength);
572 if (err != 0) {
573 return binder::Status::fromServiceSpecificError(-err,
574 String8::format("InterfaceController error: %s", strerror(-err)));
575 }
576 return binder::Status::ok();
577}
578
579binder::Status NetdNativeService::interfaceDelAddress(const std::string &ifName,
580 const std::string &addrString, int prefixLength) {
581 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
582
583 const int err = InterfaceController::delAddress(
584 ifName.c_str(), addrString.c_str(), prefixLength);
585 if (err != 0) {
586 return binder::Status::fromServiceSpecificError(-err,
587 String8::format("InterfaceController error: %s", strerror(-err)));
588 }
589 return binder::Status::ok();
590}
591
Erik Kline38e51f12018-09-06 20:14:44 +0900592namespace {
Erik Kline55b06f82016-07-04 09:57:18 +0900593
Erik Kline38e51f12018-09-06 20:14:44 +0900594std::tuple<binder::Status, const char*, const char*> getPathComponents(int32_t ipversion,
595 int32_t category) {
596 const char* ipversionStr = nullptr;
597 switch (ipversion) {
Erik Kline55b06f82016-07-04 09:57:18 +0900598 case INetd::IPV4:
Erik Kline38e51f12018-09-06 20:14:44 +0900599 ipversionStr = "ipv4";
Erik Kline55b06f82016-07-04 09:57:18 +0900600 break;
601 case INetd::IPV6:
Erik Kline38e51f12018-09-06 20:14:44 +0900602 ipversionStr = "ipv6";
Erik Kline55b06f82016-07-04 09:57:18 +0900603 break;
604 default:
Erik Kline38e51f12018-09-06 20:14:44 +0900605 return {binder::Status::fromServiceSpecificError(EAFNOSUPPORT, "Bad IP version"),
606 nullptr, nullptr};
Erik Kline55b06f82016-07-04 09:57:18 +0900607 }
608
Erik Kline38e51f12018-09-06 20:14:44 +0900609 const char* whichStr = nullptr;
610 switch (category) {
Erik Kline55b06f82016-07-04 09:57:18 +0900611 case INetd::CONF:
612 whichStr = "conf";
613 break;
614 case INetd::NEIGH:
615 whichStr = "neigh";
616 break;
617 default:
Erik Kline38e51f12018-09-06 20:14:44 +0900618 return {binder::Status::fromServiceSpecificError(EINVAL, "Bad category"), nullptr,
619 nullptr};
Erik Kline55b06f82016-07-04 09:57:18 +0900620 }
621
Erik Kline38e51f12018-09-06 20:14:44 +0900622 return {binder::Status::ok(), ipversionStr, whichStr};
623}
624
625} // namespace
626
627binder::Status NetdNativeService::getProcSysNet(int32_t ipversion, int32_t which,
628 const std::string& ifname,
629 const std::string& parameter, std::string* value) {
630 ENFORCE_PERMISSION(NETWORK_STACK);
631 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__)
632 .args(ipversion, which, ifname, parameter);
633
634 const auto pathParts = getPathComponents(ipversion, which);
635 const auto& pathStatus = std::get<0>(pathParts);
636 if (!pathStatus.isOk()) {
637 gLog.log(entry.returns(pathStatus.exceptionCode()).withAutomaticDuration());
638 return pathStatus;
Erik Kline55b06f82016-07-04 09:57:18 +0900639 }
Erik Kline38e51f12018-09-06 20:14:44 +0900640
641 const int err = InterfaceController::getParameter(std::get<1>(pathParts),
642 std::get<2>(pathParts), ifname.c_str(),
643 parameter.c_str(), value);
644 entry.returns(err);
645 if (err == 0) entry.returns(*value);
646 gLog.log(entry.withAutomaticDuration());
647 return statusFromErrcode(err);
648}
649
650binder::Status NetdNativeService::setProcSysNet(int32_t ipversion, int32_t which,
651 const std::string& ifname,
652 const std::string& parameter,
653 const std::string& value) {
654 ENFORCE_PERMISSION(NETWORK_STACK);
655 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__)
656 .args(ipversion, which, ifname, parameter, value);
657
658 const auto pathParts = getPathComponents(ipversion, which);
659 const auto& pathStatus = std::get<0>(pathParts);
660 if (!pathStatus.isOk()) {
661 gLog.log(entry.returns(pathStatus.exceptionCode()).withAutomaticDuration());
662 return pathStatus;
663 }
664
665 const int err = InterfaceController::setParameter(std::get<1>(pathParts),
666 std::get<2>(pathParts), ifname.c_str(),
667 parameter.c_str(), value.c_str());
668 gLog.log(entry.returns(err).withAutomaticDuration());
669 return statusFromErrcode(err);
Erik Kline55b06f82016-07-04 09:57:18 +0900670}
671
Robin Lee2cf56172016-09-13 18:55:42 +0900672binder::Status NetdNativeService::getMetricsReportingLevel(int *reportingLevel) {
673 // This function intentionally does not lock, since the only thing it does is one read from an
674 // atomic_int.
675 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
676 ENFORCE_DEBUGGABLE();
677
Michal Karpinskid5440112016-10-06 16:56:04 +0100678 *reportingLevel = gCtls->eventReporter.getMetricsReportingLevel();
Robin Lee2cf56172016-09-13 18:55:42 +0900679 return binder::Status::ok();
680}
681
682binder::Status NetdNativeService::setMetricsReportingLevel(const int reportingLevel) {
683 // This function intentionally does not lock, since the only thing it does is one write to an
684 // atomic_int.
685 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
686 ENFORCE_DEBUGGABLE();
687
Michal Karpinskid5440112016-10-06 16:56:04 +0100688 return (gCtls->eventReporter.setMetricsReportingLevel(reportingLevel) == 0)
689 ? binder::Status::ok()
690 : binder::Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT);
Robin Lee2cf56172016-09-13 18:55:42 +0900691}
692
Benedict Wongb2daefb2017-12-06 22:05:46 -0800693binder::Status NetdNativeService::ipSecSetEncapSocketOwner(const android::base::unique_fd& socket,
694 int newUid) {
695 ENFORCE_PERMISSION(NETWORK_STACK)
Erik Klineb31fd692018-06-06 20:50:11 +0900696 gLog.log("ipSecSetEncapSocketOwner()");
Benedict Wongb2daefb2017-12-06 22:05:46 -0800697
698 uid_t callerUid = IPCThreadState::self()->getCallingUid();
699 return asBinderStatus(gCtls->xfrmCtrl.ipSecSetEncapSocketOwner(socket, newUid, callerUid));
700}
701
Nathan Harold1a371532017-01-30 12:30:48 -0800702binder::Status NetdNativeService::ipSecAllocateSpi(
703 int32_t transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800704 const std::string& sourceAddress,
705 const std::string& destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800706 int32_t inSpi,
707 int32_t* outSpi) {
708 // Necessary locking done in IpSecService and kernel
709 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900710 gLog.log("ipSecAllocateSpi()");
ludi6e8eccd2017-08-14 14:40:37 -0700711 return asBinderStatus(gCtls->xfrmCtrl.ipSecAllocateSpi(
Nathan Harold1a371532017-01-30 12:30:48 -0800712 transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800713 sourceAddress,
714 destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800715 inSpi,
716 outSpi));
717}
718
719binder::Status NetdNativeService::ipSecAddSecurityAssociation(
720 int32_t transformId,
721 int32_t mode,
Nathan Haroldda54f122018-01-09 16:42:57 -0800722 const std::string& sourceAddress,
723 const std::string& destinationAddress,
Benedict Wong96abf482018-01-22 13:56:41 -0800724 int32_t underlyingNetId,
Nathan Harold1a371532017-01-30 12:30:48 -0800725 int32_t spi,
Di Lu2ccb3e52018-01-03 16:19:20 -0800726 int32_t markValue,
727 int32_t markMask,
Nathan Harold1a371532017-01-30 12:30:48 -0800728 const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
729 const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits,
Benedict Wongbe65b432017-08-22 21:43:14 -0700730 const std::string& aeadAlgo, const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits,
Nathan Harold1a371532017-01-30 12:30:48 -0800731 int32_t encapType,
732 int32_t encapLocalPort,
ludiec836052017-05-20 14:17:05 -0700733 int32_t encapRemotePort) {
Nathan Harold1a371532017-01-30 12:30:48 -0800734 // Necessary locking done in IpSecService and kernel
735 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900736 gLog.log("ipSecAddSecurityAssociation()");
ludi6e8eccd2017-08-14 14:40:37 -0700737 return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityAssociation(
Benedict Wongad600cb2018-05-14 17:22:35 -0700738 transformId, mode, sourceAddress, destinationAddress, underlyingNetId, spi, markValue,
739 markMask, authAlgo, authKey, authTruncBits, cryptAlgo, cryptKey, cryptTruncBits,
740 aeadAlgo, aeadKey, aeadIcvBits, encapType, encapLocalPort, encapRemotePort));
Nathan Harold1a371532017-01-30 12:30:48 -0800741}
742
743binder::Status NetdNativeService::ipSecDeleteSecurityAssociation(
744 int32_t transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800745 const std::string& sourceAddress,
746 const std::string& destinationAddress,
Di Lu2ccb3e52018-01-03 16:19:20 -0800747 int32_t spi,
748 int32_t markValue,
749 int32_t markMask) {
Nathan Harold1a371532017-01-30 12:30:48 -0800750 // Necessary locking done in IpSecService and kernel
751 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900752 gLog.log("ipSecDeleteSecurityAssociation()");
ludi6e8eccd2017-08-14 14:40:37 -0700753 return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityAssociation(
Nathan Harold1a371532017-01-30 12:30:48 -0800754 transformId,
Nathan Haroldda54f122018-01-09 16:42:57 -0800755 sourceAddress,
756 destinationAddress,
Di Lu2ccb3e52018-01-03 16:19:20 -0800757 spi,
758 markValue,
759 markMask));
Nathan Harold1a371532017-01-30 12:30:48 -0800760}
761
762binder::Status NetdNativeService::ipSecApplyTransportModeTransform(
763 const android::base::unique_fd& socket,
764 int32_t transformId,
765 int32_t direction,
Nathan Haroldda54f122018-01-09 16:42:57 -0800766 const std::string& sourceAddress,
767 const std::string& destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800768 int32_t spi) {
769 // Necessary locking done in IpSecService and kernel
770 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900771 gLog.log("ipSecApplyTransportModeTransform()");
ludi6e8eccd2017-08-14 14:40:37 -0700772 return asBinderStatus(gCtls->xfrmCtrl.ipSecApplyTransportModeTransform(
Nathan Harold1a371532017-01-30 12:30:48 -0800773 socket,
774 transformId,
775 direction,
Nathan Haroldda54f122018-01-09 16:42:57 -0800776 sourceAddress,
777 destinationAddress,
Nathan Harold1a371532017-01-30 12:30:48 -0800778 spi));
779}
780
781binder::Status NetdNativeService::ipSecRemoveTransportModeTransform(
782 const android::base::unique_fd& socket) {
783 // Necessary locking done in IpSecService and kernel
784 ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
Erik Klineb31fd692018-06-06 20:50:11 +0900785 gLog.log("ipSecRemoveTransportModeTransform()");
ludi6e8eccd2017-08-14 14:40:37 -0700786 return asBinderStatus(gCtls->xfrmCtrl.ipSecRemoveTransportModeTransform(
Nathan Harold1a371532017-01-30 12:30:48 -0800787 socket));
788}
789
Benedict Wonga04ffa72018-05-09 21:42:42 -0700790binder::Status NetdNativeService::ipSecAddSecurityPolicy(int32_t transformId, int32_t selAddrFamily,
791 int32_t direction,
Benedict Wongad600cb2018-05-14 17:22:35 -0700792 const std::string& tmplSrcAddress,
793 const std::string& tmplDstAddress,
794 int32_t spi, int32_t markValue,
795 int32_t markMask) {
Benedict Wong84a8dca2018-01-19 12:12:17 -0800796 // Necessary locking done in IpSecService and kernel
797 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900798 gLog.log("ipSecAddSecurityPolicy()");
Benedict Wong84a8dca2018-01-19 12:12:17 -0800799 return asBinderStatus(gCtls->xfrmCtrl.ipSecAddSecurityPolicy(
Benedict Wonga04ffa72018-05-09 21:42:42 -0700800 transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
801 markMask));
Benedict Wong84a8dca2018-01-19 12:12:17 -0800802}
803
Benedict Wonga04ffa72018-05-09 21:42:42 -0700804binder::Status NetdNativeService::ipSecUpdateSecurityPolicy(int32_t transformId,
805 int32_t selAddrFamily,
806 int32_t direction,
Benedict Wongad600cb2018-05-14 17:22:35 -0700807 const std::string& tmplSrcAddress,
808 const std::string& tmplDstAddress,
809 int32_t spi, int32_t markValue,
810 int32_t markMask) {
Benedict Wong84a8dca2018-01-19 12:12:17 -0800811 // Necessary locking done in IpSecService and kernel
812 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900813 gLog.log("ipSecAddSecurityPolicy()");
Benedict Wong84a8dca2018-01-19 12:12:17 -0800814 return asBinderStatus(gCtls->xfrmCtrl.ipSecUpdateSecurityPolicy(
Benedict Wonga04ffa72018-05-09 21:42:42 -0700815 transformId, selAddrFamily, direction, tmplSrcAddress, tmplDstAddress, spi, markValue,
816 markMask));
Benedict Wong84a8dca2018-01-19 12:12:17 -0800817}
818
Benedict Wonga04ffa72018-05-09 21:42:42 -0700819binder::Status NetdNativeService::ipSecDeleteSecurityPolicy(int32_t transformId,
820 int32_t selAddrFamily,
821 int32_t direction, int32_t markValue,
822 int32_t markMask) {
Benedict Wong84a8dca2018-01-19 12:12:17 -0800823 // Necessary locking done in IpSecService and kernel
824 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900825 gLog.log("ipSecAddSecurityPolicy()");
Benedict Wong84a8dca2018-01-19 12:12:17 -0800826 return asBinderStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityPolicy(
Benedict Wonga04ffa72018-05-09 21:42:42 -0700827 transformId, selAddrFamily, direction, markValue, markMask));
Benedict Wong84a8dca2018-01-19 12:12:17 -0800828}
829
manojboopathi8707f232018-01-02 14:45:47 -0800830binder::Status NetdNativeService::addVirtualTunnelInterface(
831 const std::string& deviceName,
832 const std::string& localAddress,
833 const std::string& remoteAddress,
834 int32_t iKey,
835 int32_t oKey) {
836 // Necessary locking done in IpSecService and kernel
837 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900838 gLog.log("addVirtualTunnelInterface()");
manojboopathi8707f232018-01-02 14:45:47 -0800839 int ret = gCtls->xfrmCtrl.addVirtualTunnelInterface(
840 deviceName,
841 localAddress,
842 remoteAddress,
843 iKey,
844 oKey,
845 false);
846
847 return (ret == 0) ? binder::Status::ok() :
848 asBinderStatus(netdutils::statusFromErrno(
849 ret, "Error in creating virtual tunnel interface."));
850}
851
852binder::Status NetdNativeService::updateVirtualTunnelInterface(
853 const std::string& deviceName,
854 const std::string& localAddress,
855 const std::string& remoteAddress,
856 int32_t iKey,
857 int32_t oKey) {
858 // Necessary locking done in IpSecService and kernel
859 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900860 gLog.log("updateVirtualTunnelInterface()");
manojboopathi8707f232018-01-02 14:45:47 -0800861 int ret = gCtls->xfrmCtrl.addVirtualTunnelInterface(
862 deviceName,
863 localAddress,
864 remoteAddress,
865 iKey,
866 oKey,
867 true);
868
869 return (ret == 0) ? binder::Status::ok() :
870 asBinderStatus(netdutils::statusFromErrno(
871 ret, "Error in updating virtual tunnel interface."));
872}
873
874binder::Status NetdNativeService::removeVirtualTunnelInterface(const std::string& deviceName) {
875 // Necessary locking done in IpSecService and kernel
876 ENFORCE_PERMISSION(NETWORK_STACK);
Erik Klineb31fd692018-06-06 20:50:11 +0900877 gLog.log("removeVirtualTunnelInterface()");
manojboopathi8707f232018-01-02 14:45:47 -0800878 int ret = gCtls->xfrmCtrl.removeVirtualTunnelInterface(deviceName);
879
880 return (ret == 0) ? binder::Status::ok() :
881 asBinderStatus(netdutils::statusFromErrno(
882 ret, "Error in removing virtual tunnel interface."));
883}
884
Joel Scherpelzde937962017-06-01 13:20:21 +0900885binder::Status NetdNativeService::setIPv6AddrGenMode(const std::string& ifName,
886 int32_t mode) {
887 ENFORCE_PERMISSION(NETWORK_STACK);
Nathan Harold28ccfef2018-03-16 19:02:47 -0700888 return asBinderStatus(InterfaceController::setIPv6AddrGenMode(ifName, mode));
Joel Scherpelzde937962017-06-01 13:20:21 +0900889}
890
Joel Scherpelz08b84cd2017-05-22 13:11:54 +0900891binder::Status NetdNativeService::wakeupAddInterface(const std::string& ifName,
892 const std::string& prefix, int32_t mark,
893 int32_t mask) {
894 ENFORCE_PERMISSION(NETWORK_STACK);
Nathan Harold28ccfef2018-03-16 19:02:47 -0700895 return asBinderStatus(gCtls->wakeupCtrl.addInterface(ifName, prefix, mark, mask));
Joel Scherpelz08b84cd2017-05-22 13:11:54 +0900896}
897
898binder::Status NetdNativeService::wakeupDelInterface(const std::string& ifName,
899 const std::string& prefix, int32_t mark,
900 int32_t mask) {
901 ENFORCE_PERMISSION(NETWORK_STACK);
Nathan Harold28ccfef2018-03-16 19:02:47 -0700902 return asBinderStatus(gCtls->wakeupCtrl.delInterface(ifName, prefix, mark, mask));
Joel Scherpelz08b84cd2017-05-22 13:11:54 +0900903}
904
Chenbo Feng07d43fe2017-12-21 14:38:51 -0800905binder::Status NetdNativeService::trafficCheckBpfStatsEnable(bool* ret) {
906 ENFORCE_PERMISSION(NETWORK_STACK);
907 *ret = gCtls->trafficCtrl.checkBpfStatsEnable();
908 return binder::Status::ok();
909}
910
Luke Huang0051a622018-07-23 20:30:16 +0800911binder::Status NetdNativeService::idletimerAddInterface(const std::string& ifName, int32_t timeout,
912 const std::string& classLabel) {
913 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->idletimerCtrl.lock);
914 auto entry = gLog.newEntry()
915 .prettyFunction(__PRETTY_FUNCTION__)
916 .arg(ifName)
917 .arg(timeout)
918 .arg(classLabel);
919 int res =
920 gCtls->idletimerCtrl.addInterfaceIdletimer(ifName.c_str(), timeout, classLabel.c_str());
921 gLog.log(entry.returns(res).withAutomaticDuration());
922 return statusFromErrcode(res);
923}
924
925binder::Status NetdNativeService::idletimerRemoveInterface(const std::string& ifName,
926 int32_t timeout,
927 const std::string& classLabel) {
928 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->idletimerCtrl.lock);
929 auto entry = gLog.newEntry()
930 .prettyFunction(__PRETTY_FUNCTION__)
931 .arg(ifName)
932 .arg(timeout)
933 .arg(classLabel);
934 int res = gCtls->idletimerCtrl.removeInterfaceIdletimer(ifName.c_str(), timeout,
935 classLabel.c_str());
936 gLog.log(entry.returns(res).withAutomaticDuration());
937 return statusFromErrcode(res);
938}
Luke Huanga67dd562018-07-17 19:58:25 +0800939
940binder::Status NetdNativeService::strictUidCleartextPenalty(int32_t uid, int32_t policyPenalty) {
941 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->strictCtrl.lock);
942 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid).arg(policyPenalty);
943 StrictPenalty penalty;
944 switch (policyPenalty) {
945 case INetd::PENALTY_POLICY_REJECT:
946 penalty = REJECT;
947 break;
948 case INetd::PENALTY_POLICY_LOG:
949 penalty = LOG;
950 break;
951 case INetd::PENALTY_POLICY_ACCEPT:
952 penalty = ACCEPT;
953 break;
954 default:
955 return statusFromErrcode(-EINVAL);
956 break;
957 }
958 int res = gCtls->strictCtrl.setUidCleartextPenalty((uid_t) uid, penalty);
959 gLog.log(entry.returns(res).withAutomaticDuration());
960 return statusFromErrcode(res);
961}
Luke Huange64fa382018-07-24 16:38:22 +0800962
Luke Huang6d301232018-08-01 14:05:18 +0800963binder::Status NetdNativeService::clatdStart(const std::string& ifName) {
964 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->clatdCtrl.mutex);
965 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
966 int res = gCtls->clatdCtrl.startClatd(ifName.c_str());
967 gLog.log(entry.returns(res).withAutomaticDuration());
968 return statusFromErrcode(res);
969}
970
971binder::Status NetdNativeService::clatdStop(const std::string& ifName) {
972 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->clatdCtrl.mutex);
973 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
974 int res = gCtls->clatdCtrl.stopClatd(ifName.c_str());
975 gLog.log(entry.returns(res).withAutomaticDuration());
976 return statusFromErrcode(res);
977}
Luke Huanga67dd562018-07-17 19:58:25 +0800978
Luke Huang457d4702018-08-16 15:39:15 +0800979binder::Status NetdNativeService::ipfwdEnabled(bool* status) {
980 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
981 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
982 *status = (gCtls->tetherCtrl.forwardingRequestCount() > 0) ? true : false;
983 gLog.log(entry.returns(*status).withAutomaticDuration());
984 return binder::Status::ok();
985}
986
987binder::Status NetdNativeService::ipfwdEnableForwarding(const std::string& requester) {
988 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
989 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(requester);
990 int res = (gCtls->tetherCtrl.enableForwarding(requester.c_str())) ? 0 : -EREMOTEIO;
991 gLog.log(entry.returns(res).withAutomaticDuration());
992 return statusFromErrcode(res);
993}
994
995binder::Status NetdNativeService::ipfwdDisableForwarding(const std::string& requester) {
996 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
997 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(requester);
998 int res = (gCtls->tetherCtrl.disableForwarding(requester.c_str())) ? 0 : -EREMOTEIO;
999 gLog.log(entry.returns(res).withAutomaticDuration());
1000 return statusFromErrcode(res);
1001}
1002
1003binder::Status NetdNativeService::ipfwdAddInterfaceForward(const std::string& fromIface,
1004 const std::string& toIface) {
1005 ENFORCE_PERMISSION(NETWORK_STACK);
1006 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(fromIface).arg(toIface);
1007 int res = RouteController::enableTethering(fromIface.c_str(), toIface.c_str());
1008 gLog.log(entry.returns(res).withAutomaticDuration());
1009 return statusFromErrcode(res);
1010}
1011
1012binder::Status NetdNativeService::ipfwdRemoveInterfaceForward(const std::string& fromIface,
1013 const std::string& toIface) {
1014 ENFORCE_PERMISSION(NETWORK_STACK);
1015 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(fromIface).arg(toIface);
1016 int res = RouteController::disableTethering(fromIface.c_str(), toIface.c_str());
1017 gLog.log(entry.returns(res).withAutomaticDuration());
1018 return statusFromErrcode(res);
1019}
1020
Luke Huangb5733d72018-08-21 17:17:19 +08001021binder::Status NetdNativeService::tetherStart(const std::vector<std::string>& dhcpRanges) {
1022 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1023 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(dhcpRanges);
1024 if (dhcpRanges.size() % 2 == 1) {
1025 return statusFromErrcode(-EINVAL);
1026 }
1027 int res = gCtls->tetherCtrl.startTethering(dhcpRanges);
1028 gLog.log(entry.returns(res).withAutomaticDuration());
1029 return statusFromErrcode(res);
1030}
1031
1032binder::Status NetdNativeService::tetherStop() {
1033 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1034 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
1035 int res = gCtls->tetherCtrl.stopTethering();
1036 gLog.log(entry.returns(res).withAutomaticDuration());
1037 return statusFromErrcode(res);
1038}
1039
1040binder::Status NetdNativeService::tetherIsEnabled(bool* enabled) {
1041 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1042 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
1043 *enabled = gCtls->tetherCtrl.isTetheringStarted();
1044 gLog.log(entry.returns(*enabled).withAutomaticDuration());
1045 return binder::Status::ok();
1046}
1047
1048binder::Status NetdNativeService::tetherInterfaceAdd(const std::string& ifName) {
1049 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1050 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
1051 int res = gCtls->tetherCtrl.tetherInterface(ifName.c_str());
1052 gLog.log(entry.returns(res).withAutomaticDuration());
1053 return statusFromErrcode(res);
1054}
1055
1056binder::Status NetdNativeService::tetherInterfaceRemove(const std::string& ifName) {
1057 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1058 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(ifName);
1059 int res = gCtls->tetherCtrl.untetherInterface(ifName.c_str());
1060 gLog.log(entry.returns(res).withAutomaticDuration());
1061 return statusFromErrcode(res);
1062}
1063
1064binder::Status NetdNativeService::tetherInterfaceList(std::vector<std::string>* ifList) {
1065 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1066 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
1067 for (const auto& ifname : gCtls->tetherCtrl.getTetheredInterfaceList()) {
1068 ifList->push_back(ifname);
1069 }
1070 gLog.log(entry.returns(true).withAutomaticDuration());
1071 return binder::Status::ok();
1072}
1073
1074binder::Status NetdNativeService::tetherDnsSet(int32_t netId,
1075 const std::vector<std::string>& dnsAddrs) {
1076 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1077 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId).arg(dnsAddrs);
1078 int res = gCtls->tetherCtrl.setDnsForwarders(netId, dnsAddrs);
1079 gLog.log(entry.returns(res).withAutomaticDuration());
1080 return statusFromErrcode(res);
1081}
1082
1083binder::Status NetdNativeService::tetherDnsList(std::vector<std::string>* dnsList) {
1084 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
1085 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
1086 for (const auto& fwdr : gCtls->tetherCtrl.getDnsForwarders()) {
1087 dnsList->push_back(fwdr);
1088 }
1089 gLog.log(entry.returns(true).withAutomaticDuration());
1090 return binder::Status::ok();
1091}
1092
Luke Huangb670d162018-08-23 20:01:13 +08001093binder::Status NetdNativeService::networkAddRoute(int32_t netId, const std::string& ifName,
1094 const std::string& destination,
1095 const std::string& nextHop) {
1096 // Public methods of NetworkController are thread-safe.
1097 ENFORCE_PERMISSION(NETWORK_STACK);
1098 auto entry = gLog.newEntry()
1099 .prettyFunction(__PRETTY_FUNCTION__)
1100 .arg(netId)
1101 .arg(ifName)
1102 .arg(destination)
1103 .arg(nextHop);
1104 bool legacy = false;
1105 uid_t uid = 0; // UID is only meaningful for legacy routes.
1106 int res = gCtls->netCtrl.addRoute(netId, ifName.c_str(), destination.c_str(),
1107 nextHop.empty() ? nullptr : nextHop.c_str(), legacy, uid);
1108 gLog.log(entry.returns(res).withAutomaticDuration());
1109 return statusFromErrcode(res);
1110}
1111
1112binder::Status NetdNativeService::networkRemoveRoute(int32_t netId, const std::string& ifName,
1113 const std::string& destination,
1114 const std::string& nextHop) {
1115 ENFORCE_PERMISSION(NETWORK_STACK);
1116 auto entry = gLog.newEntry()
1117 .prettyFunction(__PRETTY_FUNCTION__)
1118 .arg(netId)
1119 .arg(ifName)
1120 .arg(destination)
1121 .arg(nextHop);
1122 bool legacy = false;
1123 uid_t uid = 0; // UID is only meaningful for legacy routes.
1124 int res = gCtls->netCtrl.removeRoute(netId, ifName.c_str(), destination.c_str(),
1125 nextHop.empty() ? nullptr : nextHop.c_str(), legacy, uid);
1126 gLog.log(entry.returns(res).withAutomaticDuration());
1127 return statusFromErrcode(res);
1128}
1129
1130binder::Status NetdNativeService::networkAddLegacyRoute(int32_t netId, const std::string& ifName,
1131 const std::string& destination,
1132 const std::string& nextHop, int32_t uid) {
1133 ENFORCE_PERMISSION(NETWORK_STACK);
1134 auto entry = gLog.newEntry()
1135 .prettyFunction(__PRETTY_FUNCTION__)
1136 .arg(netId)
1137 .arg(ifName)
1138 .arg(destination)
1139 .arg(nextHop)
1140 .arg(uid);
1141 bool legacy = true;
1142 int res = gCtls->netCtrl.addRoute(netId, ifName.c_str(), destination.c_str(),
1143 nextHop.empty() ? nullptr : nextHop.c_str(), legacy,
1144 (uid_t) uid);
1145 gLog.log(entry.returns(res).withAutomaticDuration());
1146 return statusFromErrcode(res);
1147}
1148
1149binder::Status NetdNativeService::networkRemoveLegacyRoute(int32_t netId, const std::string& ifName,
1150 const std::string& destination,
1151 const std::string& nextHop,
1152 int32_t uid) {
1153 ENFORCE_PERMISSION(NETWORK_STACK);
1154 auto entry = gLog.newEntry()
1155 .prettyFunction(__PRETTY_FUNCTION__)
1156 .arg(netId)
1157 .arg(ifName)
1158 .arg(destination)
1159 .arg(nextHop)
1160 .arg(uid);
1161 bool legacy = true;
1162 int res = gCtls->netCtrl.removeRoute(netId, ifName.c_str(), destination.c_str(),
1163 nextHop.empty() ? nullptr : nextHop.c_str(), legacy,
1164 (uid_t) uid);
1165 gLog.log(entry.returns(res).withAutomaticDuration());
1166 return statusFromErrcode(res);
1167}
1168
1169binder::Status NetdNativeService::networkGetDefault(int32_t* netId) {
1170 ENFORCE_PERMISSION(NETWORK_STACK);
1171 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
1172 *netId = gCtls->netCtrl.getDefaultNetwork();
1173 gLog.log(entry.returns(*netId).withAutomaticDuration());
1174 return binder::Status::ok();
1175}
1176
1177binder::Status NetdNativeService::networkSetDefault(int32_t netId) {
1178 ENFORCE_PERMISSION(NETWORK_STACK);
1179 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId);
1180 int res = gCtls->netCtrl.setDefaultNetwork(netId);
1181 gLog.log(entry.returns(res).withAutomaticDuration());
1182 return statusFromErrcode(res);
1183}
1184
1185binder::Status NetdNativeService::networkClearDefault() {
1186 ENFORCE_PERMISSION(NETWORK_STACK);
1187 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
1188 unsigned netId = NETID_UNSET;
1189 int res = gCtls->netCtrl.setDefaultNetwork(netId);
1190 gLog.log(entry.returns(res).withAutomaticDuration());
1191 return statusFromErrcode(res);
1192}
1193
1194std::vector<uid_t> NetdNativeService::intsToUids(const std::vector<int32_t>& intUids) {
1195 return {begin(intUids), end(intUids)};
1196}
1197
1198Permission NetdNativeService::convertPermission(int32_t permission) {
1199 switch (permission) {
1200 case INetd::PERMISSION_NETWORK:
1201 return Permission::PERMISSION_NETWORK;
1202 case INetd::PERMISSION_SYSTEM:
1203 return Permission::PERMISSION_SYSTEM;
1204 default:
1205 return Permission::PERMISSION_NONE;
1206 }
1207}
1208
1209binder::Status NetdNativeService::networkSetPermissionForNetwork(int32_t netId,
1210 int32_t permission) {
1211 ENFORCE_PERMISSION(NETWORK_STACK);
1212 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(netId).arg(permission);
1213 std::vector<unsigned> netIds = {(unsigned) netId};
1214 int res = gCtls->netCtrl.setPermissionForNetworks(convertPermission(permission), netIds);
1215 gLog.log(entry.returns(res).withAutomaticDuration());
1216 return statusFromErrcode(res);
1217}
1218
1219binder::Status NetdNativeService::networkSetPermissionForUser(int32_t permission,
1220 const std::vector<int32_t>& uids) {
1221 ENFORCE_PERMISSION(NETWORK_STACK);
1222 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(permission).arg(uids);
1223 gCtls->netCtrl.setPermissionForUsers(convertPermission(permission), intsToUids(uids));
1224 gLog.log(entry.withAutomaticDuration());
1225 return binder::Status::ok();
1226}
1227
1228binder::Status NetdNativeService::networkClearPermissionForUser(const std::vector<int32_t>& uids) {
1229 ENFORCE_PERMISSION(NETWORK_STACK);
1230 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uids);
1231 Permission permission = Permission::PERMISSION_NONE;
1232 gCtls->netCtrl.setPermissionForUsers(permission, intsToUids(uids));
1233 gLog.log(entry.withAutomaticDuration());
1234 return binder::Status::ok();
1235}
1236
1237binder::Status NetdNativeService::NetdNativeService::networkSetProtectAllow(int32_t uid) {
1238 ENFORCE_PERMISSION(NETWORK_STACK);
1239 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
1240 std::vector<uid_t> uids = {(uid_t) uid};
1241 gCtls->netCtrl.allowProtect(uids);
1242 gLog.log(entry.withAutomaticDuration());
1243 return binder::Status::ok();
1244}
1245
1246binder::Status NetdNativeService::networkSetProtectDeny(int32_t uid) {
1247 ENFORCE_PERMISSION(NETWORK_STACK);
1248 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
1249 std::vector<uid_t> uids = {(uid_t) uid};
1250 gCtls->netCtrl.denyProtect(uids);
1251 gLog.log(entry.withAutomaticDuration());
1252 return binder::Status::ok();
1253}
1254
1255binder::Status NetdNativeService::networkCanProtect(int32_t uid, bool* ret) {
1256 ENFORCE_PERMISSION(NETWORK_STACK);
1257 auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(uid);
1258 *ret = gCtls->netCtrl.canProtect((uid_t) uid);
1259 gLog.log(entry.returns(*ret).withAutomaticDuration());
1260 return binder::Status::ok();
1261}
1262
Luke Huange64fa382018-07-24 16:38:22 +08001263namespace {
1264std::string ruleToString(int32_t rule) {
1265 switch (rule) {
1266 case INetd::FIREWALL_RULE_DENY:
1267 return "DENY";
1268 case INetd::FIREWALL_RULE_ALLOW:
1269 return "ALLOW";
1270 default:
1271 return "INVALID";
1272 }
1273}
1274
1275std::string typeToString(int32_t type) {
1276 switch (type) {
1277 case INetd::FIREWALL_WHITELIST:
1278 return "WHITELIST";
1279 case INetd::FIREWALL_BLACKLIST:
1280 return "BLACKLIST";
1281 default:
1282 return "INVALID";
1283 }
1284}
1285
1286std::string chainToString(int32_t chain) {
1287 switch (chain) {
1288 case INetd::FIREWALL_CHAIN_NONE:
1289 return "NONE";
1290 case INetd::FIREWALL_CHAIN_DOZABLE:
1291 return "DOZABLE";
1292 case INetd::FIREWALL_CHAIN_STANDBY:
1293 return "STANDBY";
1294 case INetd::FIREWALL_CHAIN_POWERSAVE:
1295 return "POWERSAVE";
1296 default:
1297 return "INVALID";
1298 }
1299}
1300
1301} // namespace
1302
1303binder::Status NetdNativeService::firewallSetFirewallType(int32_t firewallType) {
1304 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->firewallCtrl.lock);
1305 auto entry =
1306 gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__).arg(typeToString(firewallType));
1307 auto type = static_cast<FirewallType>(firewallType);
1308
1309 int res = gCtls->firewallCtrl.setFirewallType(type);
1310 gLog.log(entry.returns(res).withAutomaticDuration());
1311 return statusFromErrcode(res);
1312}
1313
1314binder::Status NetdNativeService::firewallSetInterfaceRule(const std::string& ifName,
1315 int32_t firewallRule) {
1316 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->firewallCtrl.lock);
1317 auto entry = gLog.newEntry()
1318 .prettyFunction(__PRETTY_FUNCTION__)
1319 .args(ifName, ruleToString(firewallRule));
1320 auto rule = static_cast<FirewallRule>(firewallRule);
1321
1322 int res = gCtls->firewallCtrl.setInterfaceRule(ifName.c_str(), rule);
1323 gLog.log(entry.returns(res).withAutomaticDuration());
1324 return statusFromErrcode(res);
1325}
1326
1327binder::Status NetdNativeService::firewallSetUidRule(int32_t childChain, int32_t uid,
1328 int32_t firewallRule) {
1329 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->firewallCtrl.lock);
1330 auto entry = gLog.newEntry()
1331 .prettyFunction(__PRETTY_FUNCTION__)
1332 .args(chainToString(childChain), uid, ruleToString(firewallRule));
1333 auto chain = static_cast<ChildChain>(childChain);
1334 auto rule = static_cast<FirewallRule>(firewallRule);
1335
1336 int res = gCtls->firewallCtrl.setUidRule(chain, uid, rule);
1337 gLog.log(entry.returns(res).withAutomaticDuration());
1338 return statusFromErrcode(res);
1339}
1340
1341binder::Status NetdNativeService::firewallEnableChildChain(int32_t childChain, bool enable) {
1342 NETD_LOCKING_RPC(NETWORK_STACK, gCtls->firewallCtrl.lock);
1343 auto entry = gLog.newEntry()
1344 .prettyFunction(__PRETTY_FUNCTION__)
1345 .args(chainToString(childChain), enable);
1346 auto chain = static_cast<ChildChain>(childChain);
1347
1348 int res = gCtls->firewallCtrl.enableChildChains(chain, enable);
1349 gLog.log(entry.returns(res).withAutomaticDuration());
1350 return statusFromErrcode(res);
1351}
1352
Lorenzo Colittie4d626e2016-02-02 17:19:04 +09001353} // namespace net
1354} // namespace android