aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Tan <samueltan@google.com>2015-08-20 11:04:41 -0700
committerSamuel Tan <samueltan@google.com>2015-08-20 11:10:32 -0700
commit71df777a3ab1a98a30e32ef482e8b28409a3989e (patch)
treed758626ca6e84d1f517321aae4b2d99f45c30a24
parent68df7cfd9156424667636ad3544d0fa9f337647d (diff)
downloaddhcpcd-6.8.2-71df777a3ab1a98a30e32ef482e8b28409a3989e.tar.gz
dhcpcd-6.8.2: add ifaddrs.c and ifaddrs.h
Add an Android implementation of ifaddrs to the dhcpcd-6.8.2 repo, which this daemon depends on. ifaddr.c cherry-picked from https://googleplex-android.git.corp.google.com/platform/external/dhcpcd/+/master at 31db56e5b40726fed587656ac1730705c79741b9. ifaddr.h cherry-picked from https://googleplex-android.git.corp.google.com/platform/external/dhcpcd/+/master at e86eee143ed21592f88a46623a81f71002430459. BUG: 22956197 Change-Id: Id19c9ee8e7c0c32b36742052f9ee63dc197aa218
-rw-r--r--ifaddrs.c149
-rw-r--r--ifaddrs.h34
2 files changed, 183 insertions, 0 deletions
diff --git a/ifaddrs.c b/ifaddrs.c
new file mode 100644
index 0000000..a88bcc1
--- /dev/null
+++ b/ifaddrs.c
@@ -0,0 +1,149 @@
+/* external/dhcpcd-6.8.2/ifaddrs.c
+** Copied from external/dhcpcd/ifaddrs.c.
+**
+** Copyright 2011, 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 <arpa/inet.h>
+#include <sys/socket.h>
+#include "ifaddrs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <netinet/ether.h>
+#include <netdb.h>
+#include <linux/if_packet.h>
+#include <netinet/if_ether.h>
+#include <linux/if_arp.h>
+#include <netutils/ifc.h>
+
+struct ifaddrs *get_interface(const char *name, sa_family_t family)
+{
+ unsigned addr, flags;
+ int masklen;
+ struct ifaddrs *ifa;
+ struct sockaddr_in *saddr = NULL;
+ struct sockaddr_in *smask = NULL;
+ struct sockaddr_ll *hwaddr = NULL;
+ unsigned char hwbuf[ETH_ALEN];
+
+ if (ifc_get_info(name, &addr, &masklen, &flags))
+ return NULL;
+
+ if ((family == AF_INET) && (addr == 0))
+ return NULL;
+
+ ifa = malloc(sizeof(struct ifaddrs));
+ if (!ifa)
+ return NULL;
+ memset(ifa, 0, sizeof(struct ifaddrs));
+
+ ifa->ifa_name = malloc(strlen(name)+1);
+ if (!ifa->ifa_name) {
+ free(ifa);
+ return NULL;
+ }
+ strcpy(ifa->ifa_name, name);
+ ifa->ifa_flags = flags;
+
+ if (family == AF_INET) {
+ saddr = malloc(sizeof(struct sockaddr_in));
+ if (saddr) {
+ saddr->sin_addr.s_addr = addr;
+ saddr->sin_family = family;
+ }
+ ifa->ifa_addr = (struct sockaddr *)saddr;
+
+ if (masklen != 0) {
+ smask = malloc(sizeof(struct sockaddr_in));
+ if (smask) {
+ smask->sin_addr.s_addr = prefixLengthToIpv4Netmask(masklen);
+ smask->sin_family = family;
+ }
+ }
+ ifa->ifa_netmask = (struct sockaddr *)smask;
+ } else if (family == AF_PACKET) {
+ if (!ifc_get_hwaddr(name, hwbuf)) {
+ hwaddr = malloc(sizeof(struct sockaddr_ll));
+ if (hwaddr) {
+ memset(hwaddr, 0, sizeof(struct sockaddr_ll));
+ hwaddr->sll_family = family;
+ /* hwaddr->sll_protocol = ETHERTYPE_IP; */
+ hwaddr->sll_hatype = ARPHRD_ETHER;
+ hwaddr->sll_halen = ETH_ALEN;
+ memcpy(hwaddr->sll_addr, hwbuf, ETH_ALEN);
+ }
+ }
+ ifa->ifa_addr = (struct sockaddr *)hwaddr;
+ ifa->ifa_netmask = (struct sockaddr *)smask;
+ }
+ return ifa;
+}
+
+int getifaddrs(struct ifaddrs **ifap)
+{
+ DIR *d;
+ struct dirent *de;
+ struct ifaddrs *ifa;
+ struct ifaddrs *ifah = NULL;
+
+ if (!ifap)
+ return -1;
+ *ifap = NULL;
+
+ if (ifc_init())
+ return -1;
+
+ d = opendir("/sys/class/net");
+ if (d == 0)
+ return -1;
+ while ((de = readdir(d))) {
+ if (de->d_name[0] == '.')
+ continue;
+ ifa = get_interface(de->d_name, AF_INET);
+ if (ifa != NULL) {
+ ifa->ifa_next = ifah;
+ ifah = ifa;
+ }
+ ifa = get_interface(de->d_name, AF_PACKET);
+ if (ifa != NULL) {
+ ifa->ifa_next = ifah;
+ ifah = ifa;
+ }
+ }
+ *ifap = ifah;
+ closedir(d);
+ ifc_close();
+ return 0;
+}
+
+void freeifaddrs(struct ifaddrs *ifa)
+{
+ struct ifaddrs *ifp;
+
+ while (ifa) {
+ ifp = ifa;
+ free(ifp->ifa_name);
+ if (ifp->ifa_addr)
+ free(ifp->ifa_addr);
+ if (ifp->ifa_netmask)
+ free(ifp->ifa_netmask);
+ ifa = ifa->ifa_next;
+ free(ifp);
+ }
+}
diff --git a/ifaddrs.h b/ifaddrs.h
new file mode 100644
index 0000000..6356653
--- /dev/null
+++ b/ifaddrs.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was generated from a glibc header of the same name.
+ *** It contains only constants, structures, and macros generated from
+ *** the original header, and thus, contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IFADDRS_H
+#define _IFADDRS_H
+
+#include <sys/socket.h>
+
+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;
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+ void *ifa_data;
+};
+
+extern int getifaddrs(struct ifaddrs **ifap);
+
+extern void freeifaddrs(struct ifaddrs *ifa);
+
+#endif