diff --git a/libc/Android.mk b/libc/Android.mk index 83e1fb505..a399b8988 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -149,7 +149,6 @@ libc_bionic_ndk_src_files := \ bionic/getpid.cpp \ bionic/gettid.cpp \ bionic/__gnu_basename.cpp \ - bionic/ifaddrs.cpp \ bionic/inotify_init.cpp \ bionic/ioctl.cpp \ bionic/lchown.cpp \ diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp deleted file mode 100644 index 5da6bcc19..000000000 --- a/libc/bionic/ifaddrs.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// The public ifaddrs struct is full of pointers. Rather than track several -// different allocations, we use a maximally-sized structure with the public -// part at offset 0, and pointers into its hidden tail. -struct ifaddrs_storage { - // Must come first, so that `ifaddrs_storage` is-a `ifaddrs`. - ifaddrs ifa; - - // The interface index, so we can match RTM_NEWADDR messages with - // earlier RTM_NEWLINK messages (to copy the interface flags). - int interface_index; - - // Storage for the pointers in `ifa`. - sockaddr_storage addr; - sockaddr_storage netmask; - sockaddr_storage ifa_ifu; - char name[IFNAMSIZ + 1]; - - ifaddrs_storage(ifaddrs** list) { - memset(this, 0, sizeof(*this)); - - // push_front onto `list`. - ifa.ifa_next = *list; - *list = reinterpret_cast(this); - } - - // Netlink gives us the address family in the header, and the - // sockaddr_in or sockaddr_in6 bytes as the payload. We need to - // stitch the two bits together into the sockaddr that's part of - // our portable interface. - void SetAddress(int family, const void* data, size_t byteCount) { - addr.ss_family = family; - memcpy(SockaddrBytes(family, &addr), data, byteCount); - ifa.ifa_addr = reinterpret_cast(&addr); - } - - void SetBroadcastAddress(int family, const void* data, size_t byteCount) { - ifa_ifu.ss_family = family; - memcpy(SockaddrBytes(family, &ifa_ifu), data, byteCount); - ifa.ifa_dstaddr = reinterpret_cast(&ifa_ifu); - } - - // Netlink gives us the prefix length as a bit count. We need to turn - // that into a BSD-compatible netmask represented by a sockaddr*. - void SetNetmask(int family, size_t prefix_length) { - // ...and work out the netmask from the prefix length. - netmask.ss_family = family; - uint8_t* dst = SockaddrBytes(family, &netmask); - memset(dst, 0xff, prefix_length / 8); - if ((prefix_length % 8) != 0) { - dst[prefix_length/8] = (0xff << (8 - (prefix_length % 8))); - } - ifa.ifa_netmask = reinterpret_cast(&netmask); - } - - private: - // Returns a pointer to the first byte in the address data (which is - // stored in network byte order). - uint8_t* SockaddrBytes(int family, sockaddr_storage* ss) { - if (family == AF_INET) { - sockaddr_in* ss4 = reinterpret_cast(ss); - return reinterpret_cast(&ss4->sin_addr); - } else if (family == AF_INET6) { - sockaddr_in6* ss6 = reinterpret_cast(ss); - return reinterpret_cast(&ss6->sin6_addr); - } - return nullptr; - } -}; - -static void __handle_netlink_response(ifaddrs** out, nlmsghdr* hdr) { - if (hdr->nlmsg_type == RTM_NEWLINK) { - ifinfomsg* ifi = reinterpret_cast(NLMSG_DATA(hdr)); - - // Create a new ifaddr entry, and set the interface index and flags. - ifaddrs_storage* new_addr = new ifaddrs_storage(out); - new_addr->interface_index = ifi->ifi_index; - new_addr->ifa.ifa_flags = ifi->ifi_flags; - - // Go through the various bits of information and find the name. - rtattr* rta = IFLA_RTA(ifi); - size_t rta_len = IFLA_PAYLOAD(hdr); - while (RTA_OK(rta, rta_len)) { - if (rta->rta_type == IFLA_IFNAME) { - if (RTA_PAYLOAD(rta) < sizeof(new_addr->name)) { - memcpy(new_addr->name, RTA_DATA(rta), RTA_PAYLOAD(rta)); - new_addr->ifa.ifa_name = new_addr->name; - } - } - rta = RTA_NEXT(rta, rta_len); - } - } else if (hdr->nlmsg_type == RTM_NEWADDR) { - ifaddrmsg* msg = reinterpret_cast(NLMSG_DATA(hdr)); - - // We should already know about this from an RTM_NEWLINK message. - ifaddrs_storage* addr = reinterpret_cast(*out); - while (addr != nullptr && addr->interface_index != static_cast(msg->ifa_index)) { - addr = reinterpret_cast(addr->ifa.ifa_next); - } - // If this is an unknown interface, ignore whatever we're being told about it. - if (addr == nullptr) return; - - // Create a new ifaddr entry and copy what we already know. - ifaddrs_storage* new_addr = new ifaddrs_storage(out); - // We can just copy the name rather than look for IFA_LABEL. - strcpy(new_addr->name, addr->name); - new_addr->ifa.ifa_name = new_addr->name; - new_addr->ifa.ifa_flags = addr->ifa.ifa_flags; - new_addr->interface_index = addr->interface_index; - - // Go through the various bits of information and find the address - // and any broadcast/destination address. - rtattr* rta = IFA_RTA(msg); - size_t rta_len = IFA_PAYLOAD(hdr); - while (RTA_OK(rta, rta_len)) { - if (rta->rta_type == IFA_ADDRESS) { - if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) { - addr->SetAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta)); - addr->SetNetmask(msg->ifa_family, msg->ifa_prefixlen); - } - } else if (rta->rta_type == IFA_BROADCAST) { - if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) { - addr->SetBroadcastAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta)); - } - } - rta = RTA_NEXT(rta, rta_len); - } - } -} - -static bool __send_netlink_request(int fd, int type) { - struct NetlinkMessage { - nlmsghdr hdr; - rtgenmsg msg; - } request; - memset(&request, 0, sizeof(request)); - request.hdr.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; - request.hdr.nlmsg_type = type; - request.hdr.nlmsg_len = sizeof(request); - request.msg.rtgen_family = AF_UNSPEC; // All families. - return (TEMP_FAILURE_RETRY(send(fd, &request, sizeof(request), 0)) == sizeof(request)); -} - -static bool __read_netlink_responses(int fd, ifaddrs** out, char* buf, size_t buf_len) { - ssize_t bytes_read; - // Read through all the responses, handing interesting ones to __handle_netlink_response. - while ((bytes_read = TEMP_FAILURE_RETRY(recv(fd, buf, buf_len, 0))) > 0) { - nlmsghdr* hdr = reinterpret_cast(buf); - for (; NLMSG_OK(hdr, static_cast(bytes_read)); hdr = NLMSG_NEXT(hdr, bytes_read)) { - if (hdr->nlmsg_type == NLMSG_DONE) return true; - if (hdr->nlmsg_type == NLMSG_ERROR) return false; - __handle_netlink_response(out, hdr); - } - } - // We only get here if recv fails before we see a NLMSG_DONE. - return false; -} - -int getifaddrs(ifaddrs** out) { - // Make cleanup easy. - *out = nullptr; - - // The kernel keeps packets under 8KiB (NLMSG_GOODSIZE), - // but that's a bit too large to go on the stack. - size_t buf_len = 8192; - char* buf = new char[buf_len]; - if (buf == nullptr) return -1; - - // Open the netlink socket and ask for all the links and addresses. - int fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); - bool okay = fd != -1 && - __send_netlink_request(fd, RTM_GETLINK) && __read_netlink_responses(fd, out, buf, buf_len) && - __send_netlink_request(fd, RTM_GETADDR) && __read_netlink_responses(fd, out, buf, buf_len); - - if (!okay) { - freeifaddrs(*out); - // Ensure that callers crash if they forget to check for success. - *out = nullptr; - } - { - int saved_errno = errno; - close(fd); - delete[] buf; - errno = saved_errno; - } - return okay ? 0 : -1; -} - -void freeifaddrs(ifaddrs* list) { - while (list != nullptr) { - ifaddrs* current = list; - list = list->ifa_next; - free(current); - } -} diff --git a/libc/include/ifaddrs.h b/libc/include/ifaddrs.h deleted file mode 100644 index 54a5a2c59..000000000 --- a/libc/include/ifaddrs.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _IFADDRS_H_ -#define _IFADDRS_H_ - -#include -#include -#include - -__BEGIN_DECLS - -struct ifaddrs { - struct ifaddrs* ifa_next; - char* ifa_name; - unsigned int ifa_flags; - struct sockaddr* ifa_addr; - struct sockaddr* ifa_netmask; - union { - struct sockaddr* ifu_broadaddr; - struct sockaddr* ifu_dstaddr; - } ifa_ifu; - void* ifa_data; -}; - -#define ifa_broadaddr ifa_ifu.ifu_broadaddr -#define ifa_dstaddr ifa_ifu.ifu_dstaddr - -void freeifaddrs(struct ifaddrs*); -int getifaddrs(struct ifaddrs**); - -__END_DECLS - -#endif diff --git a/libc/libc.arm.brillo.map b/libc/libc.arm.brillo.map index e09960bb6..4dd448146 100644 --- a/libc/libc.arm.brillo.map +++ b/libc/libc.arm.brillo.map @@ -1277,10 +1277,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; prlimit; # arm mips x86 diff --git a/libc/libc.arm.map b/libc/libc.arm.map index f24a867e9..1a666f484 100644 --- a/libc/libc.arm.map +++ b/libc/libc.arm.map @@ -1311,10 +1311,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; prlimit; # arm mips x86 diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map index 0eb0275c9..8fa46a84c 100644 --- a/libc/libc.arm64.map +++ b/libc/libc.arm64.map @@ -1156,10 +1156,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; pthread_barrierattr_destroy; diff --git a/libc/libc.map.txt b/libc/libc.map.txt index 232f85980..9eb8d01d6 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1338,10 +1338,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; prlimit; # arm mips x86 diff --git a/libc/libc.mips.brillo.map b/libc/libc.mips.brillo.map index 5b7216bc2..d4a17eaf4 100644 --- a/libc/libc.mips.brillo.map +++ b/libc/libc.mips.brillo.map @@ -1240,10 +1240,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; prlimit; # arm mips x86 diff --git a/libc/libc.mips.map b/libc/libc.mips.map index 78b224b16..5bee67eb4 100644 --- a/libc/libc.mips.map +++ b/libc/libc.mips.map @@ -1274,10 +1274,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; prlimit; # arm mips x86 diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map index 0eb0275c9..8fa46a84c 100644 --- a/libc/libc.mips64.map +++ b/libc/libc.mips64.map @@ -1156,10 +1156,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; pthread_barrierattr_destroy; diff --git a/libc/libc.x86.brillo.map b/libc/libc.x86.brillo.map index 27a7778e5..f66f21ba8 100644 --- a/libc/libc.x86.brillo.map +++ b/libc/libc.x86.brillo.map @@ -1238,10 +1238,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; prlimit; # arm mips x86 diff --git a/libc/libc.x86.map b/libc/libc.x86.map index a4b4494a5..7120e7ab4 100644 --- a/libc/libc.x86.map +++ b/libc/libc.x86.map @@ -1272,10 +1272,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; prlimit; # arm mips x86 diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map index 0eb0275c9..8fa46a84c 100644 --- a/libc/libc.x86_64.map +++ b/libc/libc.x86_64.map @@ -1156,10 +1156,8 @@ LIBC_N { __pwrite64_chk; __write_chk; fileno_unlocked; - freeifaddrs; getgrgid_r; getgrnam_r; - getifaddrs; preadv; preadv64; pthread_barrierattr_destroy; diff --git a/tests/Android.mk b/tests/Android.mk index ff9e96a9b..86c141a6b 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -61,7 +61,6 @@ libBionicStandardTests_src_files := \ ftw_test.cpp \ getauxval_test.cpp \ getcwd_test.cpp \ - ifaddrs_test.cpp \ inttypes_test.cpp \ libc_logging_test.cpp \ libgen_basename_test.cpp \ diff --git a/tests/ifaddrs_test.cpp b/tests/ifaddrs_test.cpp deleted file mode 100644 index 67857cbb9..000000000 --- a/tests/ifaddrs_test.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -TEST(ifaddrs, freeifaddrs_null) { - freeifaddrs(nullptr); -} - -TEST(ifaddrs, getifaddrs_smoke) { - ifaddrs* addrs = nullptr; - - ASSERT_EQ(0, getifaddrs(&addrs)); - ASSERT_TRUE(addrs != nullptr); - - bool saw_loopback = false; - for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) { - if (addr->ifa_name && strcmp(addr->ifa_name, "lo") == 0) saw_loopback = true; - } - ASSERT_TRUE(saw_loopback); - - freeifaddrs(addrs); -}