1 /*
2 * Copyright 2018, 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 #include "if_monitor.h"
18
19 #include <errno.h>
20 #include <linux/rtnetlink.h>
21 #include <net/if.h>
22 #include <poll.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28
29 #include <memory>
30 #include <mutex>
31 #include <thread>
32 #include <unordered_map>
33 #include <vector>
34
35 #define LOG_TAG "RIL-IFMON"
36 #include <utils/Log.h>
37
38 static const size_t kReadBufferSize = 32768;
39
40 static const size_t kControlServer = 0;
41 static const size_t kControlClient = 1;
42
43 // A list of commands that can be sent to the monitor. These should be one
44 // character long as that is all that the monitor will read and process.
45 static const char kMonitorStopCommand[] = "\1";
46 static const char kMonitorAckCommand[] = "\2";
47
addrLength(int addrFamily)48 static size_t addrLength(int addrFamily) {
49 switch (addrFamily) {
50 case AF_INET:
51 return 4;
52 case AF_INET6:
53 return 16;
54 default:
55 return 0;
56 }
57 }
58
operator ==(const struct ifAddress & left,const struct ifAddress & right)59 bool operator==(const struct ifAddress& left, const struct ifAddress& right) {
60 // The prefix length does not factor in to whether two addresses are the
61 // same or not. Only the family and the address data. This matches the
62 // kernel behavior when attempting to add the same address with different
63 // prefix lengths, those changes are rejected because the address already
64 // exists.
65 return left.family == right.family &&
66 memcmp(&left.addr, &right.addr, addrLength(left.family)) == 0;
67 }
68
69 class InterfaceMonitor {
70 public:
InterfaceMonitor()71 InterfaceMonitor() : mSocketFd(-1) {
72 mControlSocket[kControlServer] = -1;
73 mControlSocket[kControlClient] = -1;
74 }
75
~InterfaceMonitor()76 ~InterfaceMonitor() {
77 if (mControlSocket[kControlClient] != -1) {
78 ::close(mControlSocket[kControlClient]);
79 mControlSocket[kControlClient] = -1;
80 }
81 if (mControlSocket[kControlServer] != -1) {
82 ::close(mControlSocket[kControlServer]);
83 mControlSocket[kControlServer] = -1;
84 }
85
86 if (mSocketFd != -1) {
87 ::close(mSocketFd);
88 mSocketFd = -1;
89 }
90 }
91
init()92 bool init() {
93 if (mSocketFd != -1) {
94 RLOGE("InterfaceMonitor already initialized");
95 return false;
96 }
97
98 mSocketFd = ::socket(AF_NETLINK,
99 SOCK_DGRAM | SOCK_CLOEXEC,
100 NETLINK_ROUTE);
101 if (mSocketFd == -1) {
102 RLOGE("InterfaceMonitor failed to open socket: %s", strerror(errno));
103 return false;
104 }
105
106 if (::socketpair(AF_UNIX, SOCK_DGRAM, 0, mControlSocket) != 0) {
107 RLOGE("Unable to create control socket pair: %s", strerror(errno));
108 return false;
109 }
110
111 struct sockaddr_nl addr;
112 memset(&addr, 0, sizeof(addr));
113 addr.nl_family = AF_NETLINK;
114 addr.nl_groups = (1 << (RTNLGRP_IPV4_IFADDR - 1)) |
115 (1 << (RTNLGRP_IPV6_IFADDR - 1));
116
117 struct sockaddr* sa = reinterpret_cast<struct sockaddr*>(&addr);
118 if (::bind(mSocketFd, sa, sizeof(addr)) != 0) {
119 RLOGE("InterfaceMonitor failed to bind socket: %s",
120 strerror(errno));
121 return false;
122 }
123
124 return true;
125 }
126
setCallback(ifMonitorCallback callback)127 void setCallback(ifMonitorCallback callback) {
128 mOnAddressChangeCallback = callback;
129 }
130
runAsync()131 void runAsync() {
132 std::unique_lock<std::mutex> lock(mThreadMutex);
133 mThread = std::make_unique<std::thread>([this]() { run(); });
134 }
135
requestAddress()136 void requestAddress() {
137 struct {
138 struct nlmsghdr hdr;
139 struct ifaddrmsg msg;
140 char padding[16];
141 } request;
142
143 memset(&request, 0, sizeof(request));
144 request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(request.msg));
145 request.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
146 request.hdr.nlmsg_type = RTM_GETADDR;
147
148 int status = ::send(mSocketFd, &request, request.hdr.nlmsg_len, 0);
149 if (status < 0 ||
150 static_cast<unsigned int>(status) != request.hdr.nlmsg_len) {
151 if (status < 0) {
152 RLOGE("Failed to send netlink request: %s", strerror(errno));
153 } else {
154 RLOGE("Short send only sent %d out of %d bytes",
155 status, (int)request.hdr.nlmsg_len);
156 }
157 }
158 }
159
run()160 void run() {
161 requestAddress();
162
163 std::vector<struct pollfd> fds(2);
164 fds[0].events = POLLIN;
165 fds[0].fd = mControlSocket[kControlServer];
166 fds[1].events = POLLIN;
167 fds[1].fd = mSocketFd;
168 while (true) {
169 int status = ::poll(fds.data(), fds.size(), -1);
170 if (status < 0) {
171 if (errno == EINTR) {
172 // Interrupted, just keep going
173 continue;
174 }
175 // Actual error, time to quit
176 RLOGE("Polling failed: %s", strerror(errno));
177 break;
178 } else if (status == 0) {
179 // Timeout
180 continue;
181 }
182
183 if (fds[0].revents & POLLIN) {
184 // Control message received
185 char command = -1;
186 if (::read(mControlSocket[kControlServer],
187 &command,
188 sizeof(command)) == 1) {
189 if (command == kMonitorStopCommand[0]) {
190 break;
191 }
192 }
193 } else if (fds[1].revents & POLLIN) {
194 onReadAvailable();
195 }
196 }
197 ::write(mControlSocket[kControlServer], kMonitorAckCommand, 1);
198 }
199
stop()200 void stop() {
201 std::unique_lock<std::mutex> lock(mThreadMutex);
202 if (mThread) {
203 ::write(mControlSocket[kControlClient], kMonitorStopCommand, 1);
204 char ack = -1;
205 while (ack != kMonitorAckCommand[0]) {
206 ::read(mControlSocket[kControlClient], &ack, sizeof(ack));
207 }
208 mThread->join();
209 mThread.reset();
210 }
211 }
212
213 private:
onReadAvailable()214 void onReadAvailable() {
215 char buffer[kReadBufferSize];
216 struct sockaddr_storage storage;
217
218 while (true) {
219 socklen_t addrSize = sizeof(storage);
220 int status = ::recvfrom(mSocketFd,
221 buffer,
222 sizeof(buffer),
223 MSG_DONTWAIT,
224 reinterpret_cast<struct sockaddr*>(&storage),
225 &addrSize);
226 if (status < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
227 // Nothing to receive, everything is fine
228 return;
229 } else if (status < 0 && errno == EINTR) {
230 // Caught interrupt, try again
231 continue;
232 } else if (status < 0) {
233 RLOGE("InterfaceMonitor receive failed: %s", strerror(errno));
234 return;
235 } else if (addrSize < 0 ||
236 static_cast<size_t>(addrSize) != sizeof(struct sockaddr_nl)) {
237 RLOGE("InterfaceMonitor received invalid address size");
238 return;
239 }
240
241 size_t length = static_cast<size_t>(status);
242
243 auto hdr = reinterpret_cast<struct nlmsghdr*>(buffer);
244 while (NLMSG_OK(hdr, length) && hdr->nlmsg_type != NLMSG_DONE) {
245 switch (hdr->nlmsg_type) {
246 case RTM_NEWADDR:
247 case RTM_DELADDR:
248 handleAddressChange(hdr);
249 break;
250 default:
251 RLOGE("Received message type %d", (int)hdr->nlmsg_type);
252 break;
253 }
254 NLMSG_NEXT(hdr, length);
255 }
256 }
257 }
258
handleAddressChange(const struct nlmsghdr * hdr)259 void handleAddressChange(const struct nlmsghdr* hdr) {
260 if (!mOnAddressChangeCallback) {
261 return;
262 }
263
264 auto msg = reinterpret_cast<const struct ifaddrmsg*>(NLMSG_DATA(hdr));
265 std::vector<ifAddress>& ifAddrs = mAddresses[msg->ifa_index];
266
267 auto attr = reinterpret_cast<const struct rtattr*>(IFA_RTA(msg));
268 int attrLen = IFA_PAYLOAD(hdr);
269
270 bool somethingChanged = false;
271 for (;attr && RTA_OK(attr, attrLen); attr = RTA_NEXT(attr, attrLen)) {
272 if (attr->rta_type != IFA_LOCAL && attr->rta_type != IFA_ADDRESS) {
273 continue;
274 }
275
276 ifAddress addr;
277 memset(&addr, 0, sizeof(addr));
278
279 // Ensure that the payload matches the expected address length
280 if (RTA_PAYLOAD(attr) >= addrLength(msg->ifa_family)) {
281 addr.family = msg->ifa_family;
282 addr.prefix = msg->ifa_prefixlen;
283 memcpy(&addr.addr, RTA_DATA(attr), addrLength(addr.family));
284 } else {
285 RLOGE("Invalid address family (%d) and size (%d) combination",
286 int(msg->ifa_family), int(RTA_PAYLOAD(attr)));
287 continue;
288 }
289
290 auto it = std::find(ifAddrs.begin(), ifAddrs.end(), addr);
291 if (hdr->nlmsg_type == RTM_NEWADDR && it == ifAddrs.end()) {
292 // New address does not exist, add it
293 ifAddrs.push_back(addr);
294 somethingChanged = true;
295 } else if (hdr->nlmsg_type == RTM_DELADDR && it != ifAddrs.end()) {
296 // Address was removed and it exists, remove it
297 ifAddrs.erase(it);
298 somethingChanged = true;
299 }
300 }
301
302 if (somethingChanged) {
303 mOnAddressChangeCallback(msg->ifa_index,
304 ifAddrs.data(),
305 ifAddrs.size());
306 }
307 }
308
309 ifMonitorCallback mOnAddressChangeCallback;
310 std::unordered_map<unsigned int, std::vector<ifAddress>> mAddresses;
311 std::unique_ptr<std::thread> mThread;
312 std::mutex mThreadMutex;
313 int mSocketFd;
314 int mControlSocket[2];
315 };
316
317 extern "C"
ifMonitorCreate()318 struct ifMonitor* ifMonitorCreate() {
319 auto monitor = std::make_unique<InterfaceMonitor>();
320 if (!monitor || !monitor->init()) {
321 return nullptr;
322 }
323 return reinterpret_cast<struct ifMonitor*>(monitor.release());
324 }
325
326 extern "C"
ifMonitorFree(struct ifMonitor * ifMonitor)327 void ifMonitorFree(struct ifMonitor* ifMonitor) {
328 InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
329 delete monitor;
330 }
331
332 extern "C"
ifMonitorSetCallback(struct ifMonitor * ifMonitor,ifMonitorCallback callback)333 void ifMonitorSetCallback(struct ifMonitor* ifMonitor,
334 ifMonitorCallback callback) {
335 InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
336 monitor->setCallback(callback);
337 }
338
339 extern "C"
ifMonitorRunAsync(struct ifMonitor * ifMonitor)340 void ifMonitorRunAsync(struct ifMonitor* ifMonitor) {
341 InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
342
343 monitor->runAsync();
344 }
345
346 extern "C"
ifMonitorStop(struct ifMonitor * ifMonitor)347 void ifMonitorStop(struct ifMonitor* ifMonitor) {
348 InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
349
350 monitor->stop();
351 }
352
353