• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <arpa/inet.h>
20 #include <errno.h>
21 #include <ifaddrs.h>
22 #include <linux/rtnetlink.h>
23 #include <net/if.h>
24 #include <poll.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <sys/socket.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 
31 #include <memory>
32 #include <mutex>
33 #include <thread>
34 #include <unordered_map>
35 #include <unordered_set>
36 #include <vector>
37 
38 #define LOG_TAG "RIL-IFMON"
39 #include <utils/Log.h>
40 
41 static const size_t kReadBufferSize = 32768;
42 
43 static const size_t kControlServer = 0;
44 static const size_t kControlClient = 1;
45 
46 // A list of commands that can be sent to the monitor. These should be one
47 // character long as that is all that the monitor will read and process.
48 static const char kMonitorStopCommand[] = "\1";
49 static const char kMonitorAckCommand[] = "\2";
50 
addrLength(int addrFamily)51 static size_t addrLength(int addrFamily) {
52     switch (addrFamily) {
53         case AF_INET:
54             return 4;
55         case AF_INET6:
56             return 16;
57         default:
58             return 0;
59     }
60 }
61 
getSockAddrData(const struct sockaddr * addr)62 static const void* getSockAddrData(const struct sockaddr* addr) {
63     switch (addr->sa_family) {
64         case AF_INET:
65             return &reinterpret_cast<const struct sockaddr_in*>(addr)->sin_addr;
66         case AF_INET6:
67             return
68                 &reinterpret_cast<const struct sockaddr_in6*>(addr)->sin6_addr;
69         default:
70             return nullptr;
71     }
72 }
73 
operator ==(const struct ifAddress & left,const struct ifAddress & right)74 bool operator==(const struct ifAddress& left, const struct ifAddress& right) {
75     // The prefix length does not factor in to whether two addresses are the
76     // same or not. Only the family and the address data. This matches the
77     // kernel behavior when attempting to add the same address with different
78     // prefix lengths, those changes are rejected because the address already
79     // exists.
80     return left.family == right.family &&
81            memcmp(&left.addr, &right.addr, addrLength(left.family)) == 0;
82 }
83 
84 class InterfaceMonitor {
85 public:
InterfaceMonitor()86     InterfaceMonitor() : mSocketFd(-1) {
87         mControlSocket[kControlServer] = -1;
88         mControlSocket[kControlClient] = -1;
89     }
90 
~InterfaceMonitor()91     ~InterfaceMonitor() {
92         if (mControlSocket[kControlClient] != -1) {
93             ::close(mControlSocket[kControlClient]);
94             mControlSocket[kControlClient] = -1;
95         }
96         if (mControlSocket[kControlServer] != -1) {
97             ::close(mControlSocket[kControlServer]);
98             mControlSocket[kControlServer] = -1;
99         }
100 
101         if (mSocketFd != -1) {
102             ::close(mSocketFd);
103             mSocketFd = -1;
104         }
105     }
106 
init()107     bool init() {
108         if (mSocketFd != -1) {
109             RLOGE("InterfaceMonitor already initialized");
110             return false;
111         }
112 
113         mSocketFd = ::socket(AF_NETLINK,
114                              SOCK_DGRAM | SOCK_CLOEXEC,
115                              NETLINK_ROUTE);
116         if (mSocketFd == -1) {
117             RLOGE("InterfaceMonitor failed to open socket: %s", strerror(errno));
118             return false;
119         }
120 
121         if (::socketpair(AF_UNIX, SOCK_DGRAM, 0, mControlSocket) != 0) {
122             RLOGE("Unable to create control socket pair: %s", strerror(errno));
123             return false;
124         }
125 
126         struct sockaddr_nl addr;
127         memset(&addr, 0, sizeof(addr));
128         addr.nl_family = AF_NETLINK;
129         addr.nl_groups = (1 << (RTNLGRP_IPV4_IFADDR - 1)) |
130                          (1 << (RTNLGRP_IPV6_IFADDR - 1));
131 
132         struct sockaddr* sa = reinterpret_cast<struct sockaddr*>(&addr);
133         if (::bind(mSocketFd, sa, sizeof(addr)) != 0) {
134             RLOGE("InterfaceMonitor failed to bind socket: %s",
135                   strerror(errno));
136             return false;
137         }
138 
139         return true;
140     }
141 
setCallback(ifMonitorCallback callback)142     void setCallback(ifMonitorCallback callback) {
143         mOnAddressChangeCallback = callback;
144     }
145 
runAsync()146     void runAsync() {
147         std::unique_lock<std::mutex> lock(mThreadMutex);
148         mThread = std::make_unique<std::thread>([this]() { run(); });
149     }
150 
requestAddresses()151     void requestAddresses() {
152         struct ifaddrs* addresses = nullptr;
153 
154         if (getifaddrs(&addresses) != 0) {
155             RLOGE("Unable to retrieve list of interfaces, cannot get initial "
156                   "interface addresses: %s", strerror(errno));
157             return;
158         }
159 
160         for (struct ifaddrs* cur = addresses; cur; cur = cur->ifa_next) {
161             if (cur->ifa_name == nullptr ||
162                 cur->ifa_addr == nullptr ||
163                 cur->ifa_netmask == nullptr) {
164                 // Interface doesn't have all the information we need. Rely on
165                 // the netlink notification to catch this interface later if it
166                 // is configured correctly.
167                 continue;
168             }
169             if (cur->ifa_flags & IFF_LOOPBACK) {
170                 // Not interested in loopback devices, they will never be radio
171                 // interfaces.
172                 continue;
173             }
174             unsigned int ifIndex = if_nametoindex(cur->ifa_name);
175             if (ifIndex == 0) {
176                 RLOGE("Encountered interface %s with no index: %s",
177                       cur->ifa_name, strerror(errno));
178                 continue;
179             }
180             ifAddress addr;
181             addr.family = cur->ifa_addr->sa_family;
182             addr.prefix = getPrefix(cur->ifa_netmask);
183             memcpy(addr.addr,
184                    getSockAddrData(cur->ifa_addr),
185                    addrLength(cur->ifa_addr->sa_family));
186             mAddresses[ifIndex].push_back(addr);
187         }
188         freeifaddrs(addresses);
189 
190         if (mOnAddressChangeCallback) {
191             for (const auto& ifAddr : mAddresses) {
192                 mOnAddressChangeCallback(ifAddr.first,
193                                          ifAddr.second.data(),
194                                          ifAddr.second.size());
195             }
196         }
197     }
198 
getPrefix(const struct sockaddr * addr)199     int getPrefix(const struct sockaddr* addr) {
200         // This uses popcnt, a built-in instruction on some CPUs, to count
201         // the number of bits in a 32-bit word. The number of bits in a netmask
202         // equals the width of the prefix. For example a netmask of
203         // 255.255.255.0 has 24 bits set and that's also its width.
204         if (addr->sa_family == AF_INET) {
205             auto v4 = reinterpret_cast<const struct sockaddr_in*>(addr);
206             return __builtin_popcount(v4->sin_addr.s_addr);
207         } else if (addr->sa_family == AF_INET6) {
208             auto v6 = reinterpret_cast<const struct sockaddr_in6*>(addr);
209             // Copy to our own array to avoid aliasing
210             uint64_t words[2];
211             memcpy(words, v6->sin6_addr.s6_addr, sizeof(words));
212             return __builtin_popcountll(words[0]) +
213                    __builtin_popcountll(words[1]);
214         }
215         return 0;
216     }
217 
run()218     void run() {
219         requestAddresses();
220 
221         std::vector<struct pollfd> fds(2);
222         fds[0].events = POLLIN;
223         fds[0].fd = mControlSocket[kControlServer];
224         fds[1].events = POLLIN;
225         fds[1].fd = mSocketFd;
226         while (true) {
227             int status = ::poll(fds.data(), fds.size(), -1);
228             if (status < 0) {
229                 if (errno == EINTR) {
230                     // Interrupted, just keep going
231                     continue;
232                 }
233                 // Actual error, time to quit
234                 RLOGE("Polling failed: %s", strerror(errno));
235                 break;
236             } else if (status == 0) {
237                 // Timeout
238                 continue;
239             }
240 
241             if (fds[0].revents & POLLIN) {
242                 // Control message received
243                 char command = -1;
244                 if (::read(mControlSocket[kControlServer],
245                            &command,
246                            sizeof(command)) == 1) {
247                     if (command == kMonitorStopCommand[0]) {
248                         break;
249                     }
250                 }
251             } else if (fds[1].revents & POLLIN) {
252                 onReadAvailable();
253             }
254         }
255         ::write(mControlSocket[kControlServer], kMonitorAckCommand, 1);
256     }
257 
stop()258     void stop() {
259         std::unique_lock<std::mutex> lock(mThreadMutex);
260         if (mThread) {
261             ::write(mControlSocket[kControlClient], kMonitorStopCommand, 1);
262             char ack = -1;
263             while (ack != kMonitorAckCommand[0]) {
264                 ::read(mControlSocket[kControlClient], &ack, sizeof(ack));
265             }
266             mThread->join();
267             mThread.reset();
268         }
269     }
270 
271 private:
onReadAvailable()272     void onReadAvailable() {
273         char buffer[kReadBufferSize];
274         struct sockaddr_storage storage;
275 
276         while (true) {
277             socklen_t addrSize = sizeof(storage);
278             int status = ::recvfrom(mSocketFd,
279                                     buffer,
280                                     sizeof(buffer),
281                                     MSG_DONTWAIT,
282                                     reinterpret_cast<struct sockaddr*>(&storage),
283                                     &addrSize);
284             if (status < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
285                 // Nothing to receive, everything is fine
286                 return;
287             } else if (status < 0 && errno == EINTR) {
288                 // Caught interrupt, try again
289                 continue;
290             } else if (status < 0) {
291                 RLOGE("InterfaceMonitor receive failed: %s", strerror(errno));
292                 return;
293             } else if (addrSize < 0 ||
294                        static_cast<size_t>(addrSize) != sizeof(struct sockaddr_nl)) {
295                 RLOGE("InterfaceMonitor received invalid address size");
296                 return;
297             }
298 
299             size_t length = static_cast<size_t>(status);
300 
301             auto hdr = reinterpret_cast<struct nlmsghdr*>(buffer);
302             while (NLMSG_OK(hdr, length) && hdr->nlmsg_type != NLMSG_DONE) {
303                 switch (hdr->nlmsg_type) {
304                     case RTM_NEWADDR:
305                     case RTM_DELADDR:
306                         handleAddressChange(hdr);
307                         break;
308                     default:
309                         RLOGE("Received message type %d", (int)hdr->nlmsg_type);
310                         break;
311                 }
312                 hdr = NLMSG_NEXT(hdr, length);
313             }
314         }
315     }
316 
getInterfaceName(unsigned int ifIndex)317     std::string getInterfaceName(unsigned int ifIndex) {
318         char buffer[IF_NAMESIZE] = { '\0' };
319         return if_indextoname(ifIndex, buffer);
320     }
321 
handleAddressChange(const struct nlmsghdr * hdr)322     void handleAddressChange(const struct nlmsghdr* hdr) {
323         if (!mOnAddressChangeCallback) {
324             return;
325         }
326 
327         auto msg = reinterpret_cast<const struct ifaddrmsg*>(NLMSG_DATA(hdr));
328         std::vector<ifAddress>& ifAddrs = mAddresses[msg->ifa_index];
329 
330         auto attr = reinterpret_cast<const struct rtattr*>(IFA_RTA(msg));
331         int attrLen = IFA_PAYLOAD(hdr);
332 
333         bool somethingChanged = false;
334         for (;attr && RTA_OK(attr, attrLen); attr = RTA_NEXT(attr, attrLen)) {
335             if (attr->rta_type != IFA_LOCAL && attr->rta_type != IFA_ADDRESS) {
336                 continue;
337             }
338 
339             ifAddress addr;
340             memset(&addr, 0, sizeof(addr));
341 
342             // Ensure that the payload matches the expected address length
343             if (RTA_PAYLOAD(attr) >= addrLength(msg->ifa_family)) {
344                 addr.family = msg->ifa_family;
345                 addr.prefix = msg->ifa_prefixlen;
346                 memcpy(&addr.addr, RTA_DATA(attr), addrLength(addr.family));
347             } else {
348                 RLOGE("Invalid address family (%d) and size (%d) combination",
349                       int(msg->ifa_family), int(RTA_PAYLOAD(attr)));
350                 continue;
351             }
352 
353             auto it = std::find(ifAddrs.begin(), ifAddrs.end(), addr);
354             if (hdr->nlmsg_type == RTM_NEWADDR && it == ifAddrs.end()) {
355                 // New address does not exist, add it
356                 ifAddrs.push_back(addr);
357                 somethingChanged = true;
358             } else if (hdr->nlmsg_type == RTM_DELADDR && it != ifAddrs.end()) {
359                 // Address was removed and it exists, remove it
360                 ifAddrs.erase(it);
361                 somethingChanged = true;
362             }
363         }
364 
365         if (somethingChanged) {
366             mOnAddressChangeCallback(msg->ifa_index,
367                                      ifAddrs.data(),
368                                      ifAddrs.size());
369         }
370     }
371 
372     ifMonitorCallback mOnAddressChangeCallback;
373     std::unordered_map<unsigned int, std::vector<ifAddress>> mAddresses;
374     std::unique_ptr<std::thread> mThread;
375     std::mutex mThreadMutex;
376     int mSocketFd;
377     int mControlSocket[2];
378 };
379 
380 extern "C"
ifMonitorCreate()381 struct ifMonitor* ifMonitorCreate() {
382     auto monitor = std::make_unique<InterfaceMonitor>();
383     if (!monitor || !monitor->init()) {
384         return nullptr;
385     }
386     return reinterpret_cast<struct ifMonitor*>(monitor.release());
387 }
388 
389 extern "C"
ifMonitorFree(struct ifMonitor * ifMonitor)390 void ifMonitorFree(struct ifMonitor* ifMonitor) {
391     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
392     delete monitor;
393 }
394 
395 extern "C"
ifMonitorSetCallback(struct ifMonitor * ifMonitor,ifMonitorCallback callback)396 void ifMonitorSetCallback(struct ifMonitor* ifMonitor,
397                           ifMonitorCallback callback) {
398     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
399     monitor->setCallback(callback);
400 }
401 
402 extern "C"
ifMonitorRunAsync(struct ifMonitor * ifMonitor)403 void ifMonitorRunAsync(struct ifMonitor* ifMonitor) {
404     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
405 
406     monitor->runAsync();
407 }
408 
409 extern "C"
ifMonitorStop(struct ifMonitor * ifMonitor)410 void ifMonitorStop(struct ifMonitor* ifMonitor) {
411     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
412 
413     monitor->stop();
414 }
415 
416