1 /*
2 * Copyright (C) 2014 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 #define LOG_TAG "Netd"
17
18 #include "Network.h"
19
20 #include "RouteController.h"
21 #include "SockDiag.h"
22 #include "log/log.h"
23
24 #include <android-base/strings.h>
25 #include <sstream>
26
27 namespace android {
28 namespace net {
29
~Network()30 Network::~Network() {
31 if (!mInterfaces.empty()) {
32 ALOGE("deleting network with netId %u without clearing its interfaces", mNetId);
33 }
34 }
35
getNetId() const36 unsigned Network::getNetId() const {
37 return mNetId;
38 }
39
hasInterface(const std::string & interface) const40 bool Network::hasInterface(const std::string& interface) const {
41 return mInterfaces.find(interface) != mInterfaces.end();
42 }
43
getInterfaces() const44 const std::set<std::string>& Network::getInterfaces() const {
45 return mInterfaces;
46 }
47
clearInterfaces()48 int Network::clearInterfaces() {
49 while (!mInterfaces.empty()) {
50 // Make a copy of the string, so removeInterface() doesn't lose its parameter when it
51 // removes the string from the set.
52 std::string interface = *mInterfaces.begin();
53 if (int ret = removeInterface(interface)) {
54 return ret;
55 }
56 }
57 return 0;
58 }
59
toString() const60 std::string Network::toString() const {
61 const char kSeparator[] = " ";
62 std::stringstream repr;
63
64 repr << mNetId << kSeparator << getTypeString();
65
66 if (mInterfaces.size() > 0) {
67 repr << kSeparator << android::base::Join(mInterfaces, ",");
68 }
69
70 return repr.str();
71 }
72
uidRangesToString() const73 std::string Network::uidRangesToString() const {
74 if (mUidRangeMap.empty()) {
75 return "";
76 }
77
78 std::ostringstream result;
79 for (auto it = mUidRangeMap.begin(); it != mUidRangeMap.end(); ++it) {
80 result << "prio " << it->first << " " << it->second.toString();
81 if (std::next(it) != mUidRangeMap.end()) result << "; ";
82 }
83 return result.str();
84 }
85
86 // Check if the user has been added to this network. If yes, the highest priority of matching
87 // setting is returned by subPriority. Thus caller can make choice among several matching
88 // networks.
appliesToUser(uid_t uid,uint32_t * subPriority) const89 bool Network::appliesToUser(uid_t uid, uint32_t* subPriority) const {
90 for (const auto& [priority, uidRanges] : mUidRangeMap) {
91 if (uidRanges.hasUid(uid)) {
92 *subPriority = priority;
93 return true;
94 }
95 }
96 return false;
97 }
98
addToUidRangeMap(const UidRanges & uidRanges,uint32_t subPriority)99 void Network::addToUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) {
100 auto iter = mUidRangeMap.find(subPriority);
101 if (iter != mUidRangeMap.end()) {
102 iter->second.add(uidRanges);
103 } else {
104 mUidRangeMap[subPriority] = uidRanges;
105 }
106 }
107
removeFromUidRangeMap(const UidRanges & uidRanges,uint32_t subPriority)108 void Network::removeFromUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) {
109 auto iter = mUidRangeMap.find(subPriority);
110 if (iter != mUidRangeMap.end()) {
111 iter->second.remove(uidRanges);
112 if (iter->second.empty()) {
113 mUidRangeMap.erase(subPriority);
114 }
115 } else {
116 ALOGW("uidRanges with priority %u not found", subPriority);
117 }
118 }
119
canAddUidRanges(const UidRanges & uidRanges,uint32_t subPriority) const120 bool Network::canAddUidRanges(const UidRanges& uidRanges, uint32_t subPriority) const {
121 if (uidRanges.overlapsSelf()) {
122 ALOGE("uid range %s overlaps self", uidRanges.toString().c_str());
123 return false;
124 }
125
126 auto iter = mUidRangeMap.find(subPriority);
127 if (iter != mUidRangeMap.end() && uidRanges.overlaps(iter->second)) {
128 ALOGE("uid range %s overlaps priority %u %s", uidRanges.toString().c_str(), subPriority,
129 iter->second.toString().c_str());
130 return false;
131 }
132 return true;
133 }
134
isSecure() const135 bool Network::isSecure() const {
136 return mSecure;
137 }
138
Network(unsigned netId,bool secure)139 Network::Network(unsigned netId, bool secure) : mNetId(netId), mSecure(secure) {}
140
141 } // namespace net
142 } // namespace android
143