[hipl-dev] [Merge] lp:~hipl-core/hipl/android-port-new into lp:hipl

  • From: Juhani Toivonen <juhani.toivonen@xxxxxxxxxxxxxx>
  • To: mp+193420@xxxxxxxxxxxxxxxxxx
  • Date: Thu, 31 Oct 2013 14:07:28 -0000

Juhani Toivonen has proposed merging lp:~hipl-core/hipl/android-port-new into 
lp:hipl.

Requested reviews:
  Miika Komu (miika-iki)

For more details, see:
https://code.launchpad.net/~hipl-core/hipl/android-port-new/+merge/193420

Add partial Android support for HIPL

These changes allow hipd and hipconf to be compiled for Android. This does not 
produce standard installable .apk packages, but contains instructions on how to 
prepare an Android device and install hipd and hipconf on it.

Also a script for preparing an android build environment has been included in 
tools/prepare_android_toolchain.sh
It no longer thinks it is bash specific.

Some libraries and headers that are usually available in linux are not on 
Android, and they needed to be borrowed. All such code is found under the 
'android' directory.

The borrowed file android/ifaddrs.c has been changed so that the return value 
for malloc() is always checked and information of the error is carried over to 
the part of hipl using this file.

configure.ac now supports --enable-android, which means this will be a 
cross-compilation for android.

In libcore/builder.c ; function convert_byte_order needed to be changed so that 
it does not use function pointers. Byte order functions ntohl etc. are 
implemented as macros under Android and cannot be referenced by function 
pointers.

In libcore/filemanip.c ; calls to lockf() have been replaced by calls to 
flock() , another lock-file-function. They achieve the same function, flock() 
is usually available on linux, but lockf() is not available on Android.

In libhipl/init.c lowering capabilities has been conditionally disabled for 
android builds.

libhipl/netdev.c the return value of hip_cast_sa_addr has been cast to pointer 
type (const struct in6_addr *) because gcc 4.6 arm compiler otherwise considers 
the return value type to be (void *), which breaks the IN6_IS_ADDR_V4MAPPED it 
is given to. The header <linux/in6.h> is included conditionally because it 
collides with <netinet/in.h> on linux, but <netinet/in.h> does not provide 
in6_addr on android.

android.h has been conditionally included if making an android build in files 
where android behaves differently. config.h has been included in the same files 
to enable detecting whether the ongoing build is for android. 

android.h no longer includes <inttypes.h> itself; it is now included directly 
in the files that depend on it.

A section for android has been added to the manual HOWTO



-- 
https://code.launchpad.net/~hipl-core/hipl/android-port-new/+merge/193420
Your team HIPL core team is subscribed to branch lp:hipl.
=== modified file 'COPYING'
--- COPYING     2013-01-27 20:48:31 +0000
+++ COPYING     2013-10-31 14:03:43 +0000
@@ -16,9 +16,13 @@
   * doc
 
 The following directories contain code imported from other projects
-and have their own licensing conditions (GPL):
-
+and have their own licensing conditions:
+GPL:
   * libcore/gpl
+  * android/linux
+
+BSD:
+  * android
 
 (Note that tools/hipdnsproxy/DNS is from the pydns project and is covered
 by the standard Python License)
@@ -395,3 +399,58 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+BSD Licences
+============
+
+android/ifaddrs.h
+-----------------
+Copyright (c) 1995, 1999
+ Berkeley Software Design, Inc.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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.
+
+ BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
+
+
+
+android/ifaddrs.c
+-----------------
+Copyright (c) 2013, Kenneth MacKay
+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 HOLDER 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.
+

=== modified file 'INSTALL'
--- INSTALL     2013-08-12 07:55:51 +0000
+++ INSTALL     2013-10-31 14:03:43 +0000
@@ -93,6 +93,59 @@
 change the location to /etc/hip, you have to pass --sysconfdir=/etc to
 configure (or create a symbolic link).
 
+HIPL on Android
+===============
+
+There is ongoing work for a configuration tool that builds an android
+cross-compilation toolchain.
+
+1. Install all the packages for the underlying distribution as described in
+   the previous section.
+
+2. Install wget (apt-get install wget)
+   This is already included in most linux installations by default.
+
+3. Run the script: tools/prepare_android_toolchain.sh
+   The script will attempt to install a cross-compilation toolchain,
+   downloading missing components if it has to, and output the necessary
+   commands for configuring the HIPL build environment to use the toolchain.
+
+4. Follow the instructions printed at the end of the script
+
+5. In HIPL source tree, run:
+   ./configure --enable-android --disable-firewall --host=arm-linux      \
+           --prefix=/usr --sysconfdir=/etc                               \
+           CC=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-gcc         \
+           CFLAGS="-std=gnu99 -mbionic -fPIC -fno-exceptions             \
+                   --sysroot=${ANDROID_SYSROOT}"                         \
+           LDFLAGS="-Wl,-rpath-link=${ANDROID_SYSROOT}/usr/lib,\
+-L${ANDROID_SYSROOT}/usr/lib"                                            \
+           LIBS="-lc -lm -lgcc -lcrypto"
+
+It is important that there are no spaces after commas in LDFLAGS.
+
+You can then compile the source using 'make'.
+
+Currently to make it run you need to run the following commands on your device:
+mount -o remount,rw /
+mount -o remount,rw /system
+mkdir -p /var/lock
+mkdir    /etc/hip
+ln -s /system/lib/libcrypto.so /system/lib/libcrypto.so.1.0.0
+
+Then copy the config files hipd.conf and relay.conf to /etc/hip and
+the binaries hipd and hipconf to /system/xbin. You should then be able
+to run hipd and hipconf normally.
+
+You need to run hipd with the -a flag.
+The /var/lock directory does not survive reboot, it needs to be
+recreated through "mount -o remount,rw /" and "mkdir -p /var/lock".
+
+To run HIPL software on your Android device, you need root access, and
+the kernel must support IPsec BEET, the dummy network driver and null crypto.
+Instructions for preparing a Google Nexus family device can be found in
+doc/hipl_android_preparation_guide.txt
+
 
 How to contribute to HIPL
 =========================

=== modified file 'Makefile.am'
--- Makefile.am 2013-10-17 23:06:20 +0000
+++ Makefile.am 2013-10-31 14:03:43 +0000
@@ -23,7 +23,7 @@
 
 ACLOCAL_AMFLAGS  = -I m4
 
-HIPL_HEADER_LOCATIONS = hipd/*.h hipfw/*.h libcore/*.h libcore/*/*.h 
libhipl/*.h modules/*/*/*.h test/*.h test/*/*.h test/*/*/*.h
+HIPL_HEADER_LOCATIONS = android android/linux hipd/*.h hipfw/*.h libcore/*.h 
libcore/*/*.h libhipl/*.h modules/*/*/*.h test/*.h test/*/*.h test/*/*/*.h
 HIPL_HEADER_LIST = $(wildcard $(addprefix $(srcdir)/,$(HIPL_HEADER_LOCATIONS)))
 
 # For "make dist"
@@ -135,7 +135,6 @@
                       hipfw/main.c
 
 libcore_libcore_la_SOURCES = libcore/builder.c                          \
-                             libcore/capability.c                       \
                              libcore/cert.c                             \
                              libcore/certtools.c                        \
                              libcore/checksum.c                         \
@@ -167,6 +166,12 @@
                              libcore/gpl/xfrmapi.c                      \
                              modules/midauth/lib/midauth_builder.c
 
+if !HIP_ANDROID
+libcore_libcore_la_SOURCES += libcore/capability.c
+else
+libcore_libcore_la_SOURCES += android/ifaddrs.c
+endif
+
 if HIP_PERFORMANCE
 libcore_libcore_la_SOURCES += libcore/performance.c
 endif

=== added directory 'android'
=== added file 'android/android.h'
--- android/android.h   1970-01-01 00:00:00 +0000
+++ android/android.h   2013-10-31 14:03:43 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013 Aalto University and RWTH Aachen University.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef HIPL_ANDROID_H
+#define HIPL_ANDROID_H
+
+#include <stdint.h>
+
+/* Logging */
+#define ALOGE printf
+
+/* System properties */
+#define PROPERTY_KEY_MAX 32
+
+/* Networking */
+#define ICMP6_FILTER 1
+#define HOST_NAME_MAX 64
+typedef uint16_t in_port_t;
+
+#endif /* HIPL_ANDROID_H */

=== added file 'android/ifaddrs.c'
--- android/ifaddrs.c   1970-01-01 00:00:00 +0000
+++ android/ifaddrs.c   2013-10-31 14:03:43 +0000
@@ -0,0 +1,640 @@
+/*
+Copyright (c) 2013, Kenneth MacKay
+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 HOLDER 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.
+*/
+
+/*
+This file was downloaded from https://github.com/kmackay/android-ifaddrs
+
+It has been modified for HIPL in the following ways:
+- Added checking for if malloc returns NULL
+- Changed return value types of internal functions
+  to accomodate malloc checkings.
+*/
+
+#include "ifaddrs.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+typedef struct NetlinkList
+{
+    struct NetlinkList *m_next;
+    struct nlmsghdr *m_data;
+    unsigned int m_size;
+} NetlinkList;
+
+static int netlink_socket(void)
+{
+    int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+    if(l_socket < 0)
+    {
+        return -1;
+    }
+
+    struct sockaddr_nl l_addr;
+    memset(&l_addr, 0, sizeof(l_addr));
+    l_addr.nl_family = AF_NETLINK;
+    if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
+    {
+        close(l_socket);
+        return -1;
+    }
+
+    return l_socket;
+}
+
+static int netlink_send(int p_socket, int p_request)
+{
+    char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 
NLMSG_ALIGN(sizeof(struct rtgenmsg))];
+    memset(l_buffer, 0, sizeof(l_buffer));
+    struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer;
+    struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
+
+    l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
+    l_hdr->nlmsg_type = p_request;
+    l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+    l_hdr->nlmsg_pid = 0;
+    l_hdr->nlmsg_seq = p_socket;
+    l_msg->rtgen_family = AF_UNSPEC;
+
+    struct sockaddr_nl l_addr;
+    memset(&l_addr, 0, sizeof(l_addr));
+    l_addr.nl_family = AF_NETLINK;
+    return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr 
*)&l_addr, sizeof(l_addr)));
+}
+
+static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
+{
+    struct msghdr l_msg;
+    struct iovec l_iov = { p_buffer, p_len };
+    struct sockaddr_nl l_addr;
+    int l_result;
+
+    for(;;)
+    {
+        l_msg.msg_name = (void *)&l_addr;
+        l_msg.msg_namelen = sizeof(l_addr);
+        l_msg.msg_iov = &l_iov;
+        l_msg.msg_iovlen = 1;
+        l_msg.msg_control = NULL;
+        l_msg.msg_controllen = 0;
+        l_msg.msg_flags = 0;
+        int l_result = recvmsg(p_socket, &l_msg, 0);
+
+        if(l_result < 0)
+        {
+            if(errno == EINTR)
+            {
+                continue;
+            }
+            return -2;
+        }
+
+        if(l_msg.msg_flags & MSG_TRUNC)
+        { // buffer was too small
+            return -1;
+        }
+        return l_result;
+    }
+}
+
+static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int 
*p_done)
+{
+    size_t l_size = 4096;
+    void *l_buffer = NULL;
+
+    for(;;)
+    {
+        free(l_buffer);
+
+        l_buffer = malloc(l_size);
+        if (l_buffer == NULL) {
+            return NULL;
+        }
+
+        int l_read = netlink_recv(p_socket, l_buffer, l_size);
+        *p_size = l_read;
+        if(l_read == -2)
+        {
+            free(l_buffer);
+            return NULL;
+        }
+        if(l_read >= 0)
+        {
+            pid_t l_pid = getpid();
+            struct nlmsghdr *l_hdr;
+            for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned 
int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
+            {
+                if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq 
!= p_socket)
+                {
+                    continue;
+                }
+
+                if(l_hdr->nlmsg_type == NLMSG_DONE)
+                {
+                    *p_done = 1;
+                    break;
+                }
+
+                if(l_hdr->nlmsg_type == NLMSG_ERROR)
+                {
+                    free(l_buffer);
+                    return NULL;
+                }
+            }
+            return l_buffer;
+        }
+
+        l_size *= 2;
+    }
+}
+
+static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
+{
+    NetlinkList *l_item = malloc(sizeof(NetlinkList));
+    if (l_item == NULL) {
+        return NULL;
+    }
+
+    l_item->m_next = NULL;
+    l_item->m_data = p_data;
+    l_item->m_size = p_size;
+    return l_item;
+}
+
+static void freeResultList(NetlinkList *p_list)
+{
+    NetlinkList *l_cur;
+    while(p_list)
+    {
+        l_cur = p_list;
+        p_list = p_list->m_next;
+        free(l_cur->m_data);
+        free(l_cur);
+    }
+}
+
+static NetlinkList *getResultList(int p_socket, int p_request)
+{
+    if(netlink_send(p_socket, p_request) < 0)
+    {
+        return NULL;
+    }
+
+    NetlinkList *l_list = NULL;
+    NetlinkList *l_end = NULL;
+    int l_size;
+    int l_done = 0;
+    while(!l_done)
+    {
+        struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, 
&l_done);
+        if(!l_hdr)
+        { // error
+            freeResultList(l_list);
+            return NULL;
+        }
+
+        NetlinkList *l_item = newListItem(l_hdr, l_size);
+        if (!l_item) {
+            freeResultList(l_list);
+            return NULL;
+        }
+        if(!l_list)
+        {
+            l_list = l_item;
+        }
+        else
+        {
+            l_end->m_next = l_item;
+        }
+        l_end = l_item;
+    }
+    return l_list;
+}
+
+static size_t maxSize(size_t a, size_t b)
+{
+    return (a > b ? a : b);
+}
+
+static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
+{
+    switch(p_family)
+    {
+        case AF_INET:
+            return sizeof(struct sockaddr_in);
+        case AF_INET6:
+            return sizeof(struct sockaddr_in6);
+        case AF_PACKET:
+            return maxSize(sizeof(struct sockaddr_ll), offsetof(struct 
sockaddr_ll, sll_addr) + p_dataSize);
+        default:
+            return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, 
sa_data) + p_dataSize);
+    }
+}
+
+static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void 
*p_data, size_t p_size)
+{
+    switch(p_family)
+    {
+        case AF_INET:
+            memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
+            break;
+        case AF_INET6:
+            memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
+            break;
+        case AF_PACKET:
+            memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
+            ((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
+            break;
+        default:
+            memcpy(p_dest->sa_data, p_data, p_size);
+            break;
+    }
+    p_dest->sa_family = p_family;
+}
+
+static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
+{
+    if(!*p_resultList)
+    {
+        *p_resultList = p_entry;
+    }
+    else
+    {
+        struct ifaddrs *l_cur = *p_resultList;
+        while(l_cur->ifa_next)
+        {
+            l_cur = l_cur->ifa_next;
+        }
+        l_cur->ifa_next = p_entry;
+    }
+}
+
+static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, 
struct ifaddrs **p_resultList)
+{
+    struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
+
+    size_t l_nameSize = 0;
+    size_t l_addrSize = 0;
+    size_t l_dataSize = 0;
+
+    size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
+    struct rtattr *l_rta;
+    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct 
ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+        switch(l_rta->rta_type)
+        {
+            case IFLA_ADDRESS:
+            case IFLA_BROADCAST:
+                l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, 
l_rtaDataSize));
+                break;
+            case IFLA_IFNAME:
+                l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
+                break;
+            case IFLA_STATS:
+                l_dataSize += NLMSG_ALIGN(l_rtaSize);
+                break;
+            default:
+                break;
+        }
+    }
+
+    struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + 
l_addrSize + l_dataSize);
+    if (l_entry == NULL) {
+        return -1;
+    }
+
+    memset(l_entry, 0, sizeof(struct ifaddrs));
+    l_entry->ifa_name = "";
+
+    char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
+    char *l_addr = l_name + l_nameSize;
+    char *l_data = l_addr + l_addrSize;
+
+    l_entry->ifa_flags = l_info->ifi_flags;
+
+    l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
+    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct 
ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+        switch(l_rta->rta_type)
+        {
+            case IFLA_ADDRESS:
+            case IFLA_BROADCAST:
+            {
+                size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
+                makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, 
l_rtaDataSize);
+                ((struct sockaddr_ll *)l_addr)->sll_ifindex = 
l_info->ifi_index;
+                ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
+                if(l_rta->rta_type == IFLA_ADDRESS)
+                {
+                    l_entry->ifa_addr = (struct sockaddr *)l_addr;
+                }
+                else
+                {
+                    l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
+                }
+                l_addr += NLMSG_ALIGN(l_addrLen);
+                break;
+            }
+            case IFLA_IFNAME:
+                strncpy(l_name, l_rtaData, l_rtaDataSize);
+                l_name[l_rtaDataSize] = '\0';
+                l_entry->ifa_name = l_name;
+                break;
+            case IFLA_STATS:
+                memcpy(l_data, l_rtaData, l_rtaDataSize);
+                l_entry->ifa_data = l_data;
+                break;
+            default:
+                break;
+        }
+    }
+
+    addToEnd(p_resultList, l_entry);
+    p_links[l_info->ifi_index - 1] = l_entry;
+    return 0;
+}
+
+static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, 
struct ifaddrs **p_resultList)
+{
+    struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
+
+    size_t l_nameSize = 0;
+    size_t l_addrSize = 0;
+
+    int l_addedNetmask = 0;
+
+    size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
+    struct rtattr *l_rta;
+    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct 
ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+        if(l_info->ifa_family == AF_PACKET)
+        {
+            continue;
+        }
+
+        switch(l_rta->rta_type)
+        {
+            case IFA_ADDRESS:
+            case IFA_LOCAL:
+                if((l_info->ifa_family == AF_INET || l_info->ifa_family == 
AF_INET6) && !l_addedNetmask)
+                { // make room for netmask
+                    l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, 
l_rtaDataSize));
+                    l_addedNetmask = 1;
+                }
+            case IFA_BROADCAST:
+                l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, 
l_rtaDataSize));
+                break;
+            case IFA_LABEL:
+                l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
+                break;
+            default:
+                break;
+        }
+    }
+
+    struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + 
l_addrSize);
+    if (l_entry == NULL) {
+        return -1;
+    }
+
+    memset(l_entry, 0, sizeof(struct ifaddrs));
+    l_entry->ifa_name = p_links[l_info->ifa_index - 1]->ifa_name;
+
+    char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
+    char *l_addr = l_name + l_nameSize;
+
+    l_entry->ifa_flags = l_info->ifa_flags | p_links[l_info->ifa_index - 
1]->ifa_flags;
+
+    l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
+    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct 
ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+    {
+        void *l_rtaData = RTA_DATA(l_rta);
+        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+        switch(l_rta->rta_type)
+        {
+            case IFA_ADDRESS:
+            case IFA_BROADCAST:
+            case IFA_LOCAL:
+            {
+                size_t l_addrLen = calcAddrLen(l_info->ifa_family, 
l_rtaDataSize);
+                makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, 
l_rtaData, l_rtaDataSize);
+                if(l_info->ifa_family == AF_INET6)
+                {
+                    if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || 
IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
+                    {
+                        ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = 
l_info->ifa_index;
+                    }
+                }
+
+                if(l_rta->rta_type == IFA_ADDRESS)
+                { // apparently in a point-to-point network IFA_ADDRESS 
contains the dest address and IFA_LOCAL contains the local address
+                    if(l_entry->ifa_addr)
+                    {
+                        l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
+                    }
+                    else
+                    {
+                        l_entry->ifa_addr = (struct sockaddr *)l_addr;
+                    }
+                }
+                else if(l_rta->rta_type == IFA_LOCAL)
+                {
+                    if(l_entry->ifa_addr)
+                    {
+                        l_entry->ifa_dstaddr = l_entry->ifa_addr;
+                    }
+                    l_entry->ifa_addr = (struct sockaddr *)l_addr;
+                }
+                else
+                {
+                    l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
+                }
+                l_addr += NLMSG_ALIGN(l_addrLen);
+                break;
+            }
+            case IFA_LABEL:
+                strncpy(l_name, l_rtaData, l_rtaDataSize);
+                l_name[l_rtaDataSize] = '\0';
+                l_entry->ifa_name = l_name;
+                break;
+            default:
+                break;
+        }
+    }
+
+    if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || 
l_entry->ifa_addr->sa_family == AF_INET6))
+    {
+        unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 
128);
+        unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix 
: l_info->ifa_prefixlen);
+        char l_mask[16] = {0};
+        unsigned i;
+        for(i=0; i<(l_prefix/8); ++i)
+        {
+            l_mask[i] = 0xff;
+        }
+        l_mask[i] = 0xff << (8 - (l_prefix % 8));
+
+        makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, 
l_mask, l_maxPrefix / 8);
+        l_entry->ifa_netmask = (struct sockaddr *)l_addr;
+    }
+
+    addToEnd(p_resultList, l_entry);
+    return 0;
+}
+
+static int interpret(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs 
**p_links, struct ifaddrs **p_resultList)
+{
+    pid_t l_pid = getpid();
+    for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
+    {
+        unsigned int l_nlsize = p_netlinkList->m_size;
+        struct nlmsghdr *l_hdr;
+        for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = 
NLMSG_NEXT(l_hdr, l_nlsize))
+        {
+            if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != 
p_socket)
+            {
+                continue;
+            }
+
+            if(l_hdr->nlmsg_type == NLMSG_DONE)
+            {
+                break;
+            }
+
+            if(l_hdr->nlmsg_type == RTM_NEWLINK)
+            {
+                if (interpretLink(l_hdr, p_links, p_resultList) == -1) {
+                    return -1;
+                }
+            }
+            else if(l_hdr->nlmsg_type == RTM_NEWADDR)
+            {
+                if (interpretAddr(l_hdr, p_links, p_resultList) == -1) {
+                    return -1;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+static unsigned countLinks(int p_socket, NetlinkList *p_netlinkList)
+{
+    unsigned l_links = 0;
+    pid_t l_pid = getpid();
+    for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
+    {
+        unsigned int l_nlsize = p_netlinkList->m_size;
+        struct nlmsghdr *l_hdr;
+        for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = 
NLMSG_NEXT(l_hdr, l_nlsize))
+        {
+            if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != 
p_socket)
+            {
+                continue;
+            }
+
+            if(l_hdr->nlmsg_type == NLMSG_DONE)
+            {
+                break;
+            }
+
+            if(l_hdr->nlmsg_type == RTM_NEWLINK)
+            {
+                ++l_links;
+            }
+        }
+    }
+
+    return l_links;
+}
+
+int getifaddrs(struct ifaddrs **ifap)
+{
+    if(!ifap)
+    {
+        return -1;
+    }
+    *ifap = NULL;
+
+    int l_socket = netlink_socket();
+    if(l_socket < 0)
+    {
+        return -1;
+    }
+
+    NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK);
+    if(!l_linkResults)
+    {
+        close(l_socket);
+        return -1;
+    }
+
+    NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR);
+    if(!l_addrResults)
+    {
+        close(l_socket);
+        freeResultList(l_linkResults);
+        return -1;
+    }
+
+    unsigned l_numLinks = countLinks(l_socket, l_linkResults) + 
countLinks(l_socket, l_addrResults);
+    struct ifaddrs *l_links[l_numLinks];
+    memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *));
+
+    if (interpret(l_socket, l_linkResults, l_links, ifap) == -1) {
+        return -1;
+    }
+    if (interpret(l_socket, l_addrResults, l_links, ifap) == -1) {
+        return -1;
+    }
+
+    freeResultList(l_linkResults);
+    freeResultList(l_addrResults);
+    close(l_socket);
+    return 0;
+}
+
+void freeifaddrs(struct ifaddrs *ifa)
+{
+    struct ifaddrs *l_cur;
+    while(ifa)
+    {
+        l_cur = ifa;
+        ifa = ifa->ifa_next;
+        free(l_cur);
+    }
+}

=== added file 'android/ifaddrs.h'
--- android/ifaddrs.h   1970-01-01 00:00:00 +0000
+++ android/ifaddrs.h   2013-10-31 14:03:43 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 1999
+ *     Berkeley Software Design, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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.
+ *
+ *     BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
+ */
+
+#ifndef        _IFADDRS_H_
+#define        _IFADDRS_H_
+
+struct ifaddrs {
+       struct ifaddrs  *ifa_next;
+       char            *ifa_name;
+       unsigned int     ifa_flags;
+       struct sockaddr *ifa_addr;
+       struct sockaddr *ifa_netmask;
+       struct sockaddr *ifa_dstaddr;
+       void            *ifa_data;
+};
+
+/*
+ * This may have been defined in <net/if.h>.  Note that if <net/if.h> is
+ * to be included it must be included before this header file.
+ */
+#ifndef        ifa_broadaddr
+#define        ifa_broadaddr   ifa_dstaddr     /* broadcast address interface 
*/
+#endif
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int getifaddrs(struct ifaddrs **ifap);
+extern void freeifaddrs(struct ifaddrs *ifa);
+__END_DECLS
+
+#endif

=== added directory 'android/linux'
=== added file 'android/linux/xfrm.h'
--- android/linux/xfrm.h        1970-01-01 00:00:00 +0000
+++ android/linux/xfrm.h        2013-10-31 14:03:43 +0000
@@ -0,0 +1,504 @@
+#ifndef _LINUX_XFRM_H
+#define _LINUX_XFRM_H
+
+#include <linux/types.h>
+
+/* All of the structures in this file may not change size as they are
+ * passed into the kernel from userspace via netlink sockets.
+ */
+
+/* Structure to encapsulate addresses. I do not want to use
+ * "standard" structure. My apologies.
+ */
+typedef union {
+       __be32          a4;
+       __be32          a6[4];
+} xfrm_address_t;
+
+/* Ident of a specific xfrm_state. It is used on input to lookup
+ * the state by (spi,daddr,ah/esp) or to store information about
+ * spi, protocol and tunnel address on output.
+ */
+struct xfrm_id {
+       xfrm_address_t  daddr;
+       __be32          spi;
+       __u8            proto;
+};
+
+struct xfrm_sec_ctx {
+       __u8    ctx_doi;
+       __u8    ctx_alg;
+       __u16   ctx_len;
+       __u32   ctx_sid;
+       char    ctx_str[0];
+};
+
+/* Security Context Domains of Interpretation */
+#define XFRM_SC_DOI_RESERVED 0
+#define XFRM_SC_DOI_LSM 1
+
+/* Security Context Algorithms */
+#define XFRM_SC_ALG_RESERVED 0
+#define XFRM_SC_ALG_SELINUX 1
+
+/* Selector, used as selector both on policy rules (SPD) and SAs. */
+
+struct xfrm_selector {
+       xfrm_address_t  daddr;
+       xfrm_address_t  saddr;
+       __be16  dport;
+       __be16  dport_mask;
+       __be16  sport;
+       __be16  sport_mask;
+       __u16   family;
+       __u8    prefixlen_d;
+       __u8    prefixlen_s;
+       __u8    proto;
+       int     ifindex;
+       __kernel_uid32_t        user;
+};
+
+#define XFRM_INF (~(__u64)0)
+
+struct xfrm_lifetime_cfg {
+       __u64   soft_byte_limit;
+       __u64   hard_byte_limit;
+       __u64   soft_packet_limit;
+       __u64   hard_packet_limit;
+       __u64   soft_add_expires_seconds;
+       __u64   hard_add_expires_seconds;
+       __u64   soft_use_expires_seconds;
+       __u64   hard_use_expires_seconds;
+};
+
+struct xfrm_lifetime_cur {
+       __u64   bytes;
+       __u64   packets;
+       __u64   add_time;
+       __u64   use_time;
+};
+
+struct xfrm_replay_state {
+       __u32   oseq;
+       __u32   seq;
+       __u32   bitmap;
+};
+
+#define XFRMA_REPLAY_ESN_MAX   4096
+
+struct xfrm_replay_state_esn {
+       unsigned int    bmp_len;
+       __u32           oseq;
+       __u32           seq;
+       __u32           oseq_hi;
+       __u32           seq_hi;
+       __u32           replay_window;
+       __u32           bmp[0];
+};
+
+struct xfrm_algo {
+       char            alg_name[64];
+       unsigned int    alg_key_len;    /* in bits */
+       char            alg_key[0];
+};
+
+struct xfrm_algo_auth {
+       char            alg_name[64];
+       unsigned int    alg_key_len;    /* in bits */
+       unsigned int    alg_trunc_len;  /* in bits */
+       char            alg_key[0];
+};
+
+struct xfrm_algo_aead {
+       char            alg_name[64];
+       unsigned int    alg_key_len;    /* in bits */
+       unsigned int    alg_icv_len;    /* in bits */
+       char            alg_key[0];
+};
+
+struct xfrm_stats {
+       __u32   replay_window;
+       __u32   replay;
+       __u32   integrity_failed;
+};
+
+enum {
+       XFRM_POLICY_TYPE_MAIN   = 0,
+       XFRM_POLICY_TYPE_SUB    = 1,
+       XFRM_POLICY_TYPE_MAX    = 2,
+       XFRM_POLICY_TYPE_ANY    = 255
+};
+
+enum {
+       XFRM_POLICY_IN  = 0,
+       XFRM_POLICY_OUT = 1,
+       XFRM_POLICY_FWD = 2,
+       XFRM_POLICY_MASK = 3,
+       XFRM_POLICY_MAX = 3
+};
+
+enum {
+       XFRM_SHARE_ANY,         /* No limitations */
+       XFRM_SHARE_SESSION,     /* For this session only */
+       XFRM_SHARE_USER,        /* For this user only */
+       XFRM_SHARE_UNIQUE       /* Use once */
+};
+
+#define XFRM_MODE_TRANSPORT 0
+#define XFRM_MODE_TUNNEL 1
+#define XFRM_MODE_ROUTEOPTIMIZATION 2
+#define XFRM_MODE_IN_TRIGGER 3
+#define XFRM_MODE_BEET 4
+#define XFRM_MODE_MAX 5
+
+/* Netlink configuration messages.  */
+enum {
+       XFRM_MSG_BASE = 0x10,
+
+       XFRM_MSG_NEWSA = 0x10,
+#define XFRM_MSG_NEWSA XFRM_MSG_NEWSA
+       XFRM_MSG_DELSA,
+#define XFRM_MSG_DELSA XFRM_MSG_DELSA
+       XFRM_MSG_GETSA,
+#define XFRM_MSG_GETSA XFRM_MSG_GETSA
+
+       XFRM_MSG_NEWPOLICY,
+#define XFRM_MSG_NEWPOLICY XFRM_MSG_NEWPOLICY
+       XFRM_MSG_DELPOLICY,
+#define XFRM_MSG_DELPOLICY XFRM_MSG_DELPOLICY
+       XFRM_MSG_GETPOLICY,
+#define XFRM_MSG_GETPOLICY XFRM_MSG_GETPOLICY
+
+       XFRM_MSG_ALLOCSPI,
+#define XFRM_MSG_ALLOCSPI XFRM_MSG_ALLOCSPI
+       XFRM_MSG_ACQUIRE,
+#define XFRM_MSG_ACQUIRE XFRM_MSG_ACQUIRE
+       XFRM_MSG_EXPIRE,
+#define XFRM_MSG_EXPIRE XFRM_MSG_EXPIRE
+
+       XFRM_MSG_UPDPOLICY,
+#define XFRM_MSG_UPDPOLICY XFRM_MSG_UPDPOLICY
+       XFRM_MSG_UPDSA,
+#define XFRM_MSG_UPDSA XFRM_MSG_UPDSA
+
+       XFRM_MSG_POLEXPIRE,
+#define XFRM_MSG_POLEXPIRE XFRM_MSG_POLEXPIRE
+
+       XFRM_MSG_FLUSHSA,
+#define XFRM_MSG_FLUSHSA XFRM_MSG_FLUSHSA
+       XFRM_MSG_FLUSHPOLICY,
+#define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY
+
+       XFRM_MSG_NEWAE,
+#define XFRM_MSG_NEWAE XFRM_MSG_NEWAE
+       XFRM_MSG_GETAE,
+#define XFRM_MSG_GETAE XFRM_MSG_GETAE
+
+       XFRM_MSG_REPORT,
+#define XFRM_MSG_REPORT XFRM_MSG_REPORT
+
+       XFRM_MSG_MIGRATE,
+#define XFRM_MSG_MIGRATE XFRM_MSG_MIGRATE
+
+       XFRM_MSG_NEWSADINFO,
+#define XFRM_MSG_NEWSADINFO XFRM_MSG_NEWSADINFO
+       XFRM_MSG_GETSADINFO,
+#define XFRM_MSG_GETSADINFO XFRM_MSG_GETSADINFO
+
+       XFRM_MSG_NEWSPDINFO,
+#define XFRM_MSG_NEWSPDINFO XFRM_MSG_NEWSPDINFO
+       XFRM_MSG_GETSPDINFO,
+#define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
+
+       XFRM_MSG_MAPPING,
+#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
+       __XFRM_MSG_MAX
+};
+#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
+
+#define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
+
+/*
+ * Generic LSM security context for comunicating to user space
+ * NOTE: Same format as sadb_x_sec_ctx
+ */
+struct xfrm_user_sec_ctx {
+       __u16                   len;
+       __u16                   exttype;
+       __u8                    ctx_alg;  /* LSMs: e.g., selinux == 1 */
+       __u8                    ctx_doi;
+       __u16                   ctx_len;
+};
+
+struct xfrm_user_tmpl {
+       struct xfrm_id          id;
+       __u16                   family;
+       xfrm_address_t          saddr;
+       __u32                   reqid;
+       __u8                    mode;
+       __u8                    share;
+       __u8                    optional;
+       __u32                   aalgos;
+       __u32                   ealgos;
+       __u32                   calgos;
+};
+
+struct xfrm_encap_tmpl {
+       __u16           encap_type;
+       __be16          encap_sport;
+       __be16          encap_dport;
+       xfrm_address_t  encap_oa;
+};
+
+/* AEVENT flags  */
+enum xfrm_ae_ftype_t {
+       XFRM_AE_UNSPEC,
+       XFRM_AE_RTHR=1, /* replay threshold*/
+       XFRM_AE_RVAL=2, /* replay value */
+       XFRM_AE_LVAL=4, /* lifetime value */
+       XFRM_AE_ETHR=8, /* expiry timer threshold */
+       XFRM_AE_CR=16, /* Event cause is replay update */
+       XFRM_AE_CE=32, /* Event cause is timer expiry */
+       XFRM_AE_CU=64, /* Event cause is policy update */
+       __XFRM_AE_MAX
+
+#define XFRM_AE_MAX (__XFRM_AE_MAX - 1)
+};
+
+struct xfrm_userpolicy_type {
+       __u8            type;
+       __u16           reserved1;
+       __u8            reserved2;
+};
+
+/* Netlink message attributes.  */
+enum xfrm_attr_type_t {
+       XFRMA_UNSPEC,
+       XFRMA_ALG_AUTH,         /* struct xfrm_algo */
+       XFRMA_ALG_CRYPT,        /* struct xfrm_algo */
+       XFRMA_ALG_COMP,         /* struct xfrm_algo */
+       XFRMA_ENCAP,            /* struct xfrm_algo + struct xfrm_encap_tmpl */
+       XFRMA_TMPL,             /* 1 or more struct xfrm_user_tmpl */
+       XFRMA_SA,               /* struct xfrm_usersa_info  */
+       XFRMA_POLICY,           /*struct xfrm_userpolicy_info */
+       XFRMA_SEC_CTX,          /* struct xfrm_sec_ctx */
+       XFRMA_LTIME_VAL,
+       XFRMA_REPLAY_VAL,
+       XFRMA_REPLAY_THRESH,
+       XFRMA_ETIMER_THRESH,
+       XFRMA_SRCADDR,          /* xfrm_address_t */
+       XFRMA_COADDR,           /* xfrm_address_t */
+       XFRMA_LASTUSED,         /* unsigned long  */
+       XFRMA_POLICY_TYPE,      /* struct xfrm_userpolicy_type */
+       XFRMA_MIGRATE,
+       XFRMA_ALG_AEAD,         /* struct xfrm_algo_aead */
+       XFRMA_KMADDRESS,        /* struct xfrm_user_kmaddress */
+       XFRMA_ALG_AUTH_TRUNC,   /* struct xfrm_algo_auth */
+       XFRMA_MARK,             /* struct xfrm_mark */
+       XFRMA_TFCPAD,           /* __u32 */
+       XFRMA_REPLAY_ESN_VAL,   /* struct xfrm_replay_esn */
+       __XFRMA_MAX
+
+#define XFRMA_MAX (__XFRMA_MAX - 1)
+};
+
+struct xfrm_mark {
+       __u32           v; /* value */
+       __u32           m; /* mask */
+};
+
+enum xfrm_sadattr_type_t {
+       XFRMA_SAD_UNSPEC,
+       XFRMA_SAD_CNT,
+       XFRMA_SAD_HINFO,
+       __XFRMA_SAD_MAX
+
+#define XFRMA_SAD_MAX (__XFRMA_SAD_MAX - 1)
+};
+
+struct xfrmu_sadhinfo {
+       __u32 sadhcnt; /* current hash bkts */
+       __u32 sadhmcnt; /* max allowed hash bkts */
+};
+
+enum xfrm_spdattr_type_t {
+       XFRMA_SPD_UNSPEC,
+       XFRMA_SPD_INFO,
+       XFRMA_SPD_HINFO,
+       __XFRMA_SPD_MAX
+
+#define XFRMA_SPD_MAX (__XFRMA_SPD_MAX - 1)
+};
+
+struct xfrmu_spdinfo {
+       __u32 incnt;
+       __u32 outcnt;
+       __u32 fwdcnt;
+       __u32 inscnt;
+       __u32 outscnt;
+       __u32 fwdscnt;
+};
+
+struct xfrmu_spdhinfo {
+       __u32 spdhcnt;
+       __u32 spdhmcnt;
+};
+
+struct xfrm_usersa_info {
+       struct xfrm_selector            sel;
+       struct xfrm_id                  id;
+       xfrm_address_t                  saddr;
+       struct xfrm_lifetime_cfg        lft;
+       struct xfrm_lifetime_cur        curlft;
+       struct xfrm_stats               stats;
+       __u32                           seq;
+       __u32                           reqid;
+       __u16                           family;
+       __u8                            mode;           /* XFRM_MODE_xxx */
+       __u8                            replay_window;
+       __u8                            flags;
+#define XFRM_STATE_NOECN       1
+#define XFRM_STATE_DECAP_DSCP  2
+#define XFRM_STATE_NOPMTUDISC  4
+#define XFRM_STATE_WILDRECV    8
+#define XFRM_STATE_ICMP                16
+#define XFRM_STATE_AF_UNSPEC   32
+#define XFRM_STATE_ALIGN4      64
+#define XFRM_STATE_ESN         128
+};
+
+struct xfrm_usersa_id {
+       xfrm_address_t                  daddr;
+       __be32                          spi;
+       __u16                           family;
+       __u8                            proto;
+};
+
+struct xfrm_aevent_id {
+       struct xfrm_usersa_id           sa_id;
+       xfrm_address_t                  saddr;
+       __u32                           flags;
+       __u32                           reqid;
+};
+
+struct xfrm_userspi_info {
+       struct xfrm_usersa_info         info;
+       __u32                           min;
+       __u32                           max;
+};
+
+struct xfrm_userpolicy_info {
+       struct xfrm_selector            sel;
+       struct xfrm_lifetime_cfg        lft;
+       struct xfrm_lifetime_cur        curlft;
+       __u32                           priority;
+       __u32                           index;
+       __u8                            dir;
+       __u8                            action;
+#define XFRM_POLICY_ALLOW      0
+#define XFRM_POLICY_BLOCK      1
+       __u8                            flags;
+#define XFRM_POLICY_LOCALOK    1       /* Allow user to override global policy 
*/
+       /* Automatically expand selector to include matching ICMP payloads. */
+#define XFRM_POLICY_ICMP       2
+       __u8                            share;
+};
+
+struct xfrm_userpolicy_id {
+       struct xfrm_selector            sel;
+       __u32                           index;
+       __u8                            dir;
+};
+
+struct xfrm_user_acquire {
+       struct xfrm_id                  id;
+       xfrm_address_t                  saddr;
+       struct xfrm_selector            sel;
+       struct xfrm_userpolicy_info     policy;
+       __u32                           aalgos;
+       __u32                           ealgos;
+       __u32                           calgos;
+       __u32                           seq;
+};
+
+struct xfrm_user_expire {
+       struct xfrm_usersa_info         state;
+       __u8                            hard;
+};
+
+struct xfrm_user_polexpire {
+       struct xfrm_userpolicy_info     pol;
+       __u8                            hard;
+};
+
+struct xfrm_usersa_flush {
+       __u8                            proto;
+};
+
+struct xfrm_user_report {
+       __u8                            proto;
+       struct xfrm_selector            sel;
+};
+
+/* Used by MIGRATE to pass addresses IKE should use to perform
+ * SA negotiation with the peer */
+struct xfrm_user_kmaddress {
+       xfrm_address_t                  local;
+       xfrm_address_t                  remote;
+       __u32                           reserved;
+       __u16                           family;
+};
+
+struct xfrm_user_migrate {
+       xfrm_address_t                  old_daddr;
+       xfrm_address_t                  old_saddr;
+       xfrm_address_t                  new_daddr;
+       xfrm_address_t                  new_saddr;
+       __u8                            proto;
+       __u8                            mode;
+       __u16                           reserved;
+       __u32                           reqid;
+       __u16                           old_family;
+       __u16                           new_family;
+};
+
+struct xfrm_user_mapping {
+       struct xfrm_usersa_id           id;
+       __u32                           reqid;
+       xfrm_address_t                  old_saddr;
+       xfrm_address_t                  new_saddr;
+       __be16                          old_sport;
+       __be16                          new_sport;
+};
+
+/* backwards compatibility for userspace */
+#define XFRMGRP_ACQUIRE                1
+#define XFRMGRP_EXPIRE         2
+#define XFRMGRP_SA             4
+#define XFRMGRP_POLICY         8
+#define XFRMGRP_REPORT         0x20
+
+enum xfrm_nlgroups {
+       XFRMNLGRP_NONE,
+#define XFRMNLGRP_NONE         XFRMNLGRP_NONE
+       XFRMNLGRP_ACQUIRE,
+#define XFRMNLGRP_ACQUIRE      XFRMNLGRP_ACQUIRE
+       XFRMNLGRP_EXPIRE,
+#define XFRMNLGRP_EXPIRE       XFRMNLGRP_EXPIRE
+       XFRMNLGRP_SA,
+#define XFRMNLGRP_SA           XFRMNLGRP_SA
+       XFRMNLGRP_POLICY,
+#define XFRMNLGRP_POLICY       XFRMNLGRP_POLICY
+       XFRMNLGRP_AEVENTS,
+#define XFRMNLGRP_AEVENTS      XFRMNLGRP_AEVENTS
+       XFRMNLGRP_REPORT,
+#define XFRMNLGRP_REPORT       XFRMNLGRP_REPORT
+       XFRMNLGRP_MIGRATE,
+#define XFRMNLGRP_MIGRATE      XFRMNLGRP_MIGRATE
+       XFRMNLGRP_MAPPING,
+#define XFRMNLGRP_MAPPING      XFRMNLGRP_MAPPING
+       __XFRMNLGRP_MAX
+};
+#define XFRMNLGRP_MAX  (__XFRMNLGRP_MAX - 1)
+
+#endif /* _LINUX_XFRM_H */

=== modified file 'configure.ac'
--- configure.ac        2013-08-06 19:17:14 +0000
+++ configure.ac        2013-10-31 14:03:43 +0000
@@ -122,6 +122,23 @@
 
 # configure options
 
+AC_ARG_ENABLE(android,
+               AS_HELP_STRING([--enable-android],
+                              [Enable android (default is NO)]),
+               [ac_cv_use_android=$enableval],
+               [ac_cv_use_android=no])
+AC_CACHE_CHECK([whether to build for Android],
+               [ac_cv_use_android],
+               [ac_cv_use_android=no])
+if test x"$ac_cv_use_android" = x"yes"; then
+    AC_DEFINE(CONFIG_HIP_ANDROID)
+    AC_SUBST(AM_CFLAGS, "-std=gnu99 -mbionic -fPIC -fno-exceptions")
+    AC_SUBST(AM_CFLAGS, "$AM_CFLAGS --sysroot=${ANDROID_SYSROOT}")
+    AC_SUBST(AM_CFLAGS, "$AM_CFLAGS -I android")
+    AH_TEMPLATE(CONFIG_HIP_ANDROID, [Defined to 1 if android build is 
enabled.])
+fi
+AM_CONDITIONAL(HIP_ANDROID, test x"$ac_cv_use_android" = x"yes")
+
 AC_ARG_ENABLE(firewall,
                AS_HELP_STRING([--disable-firewall],
                               [HIP firewall daemon (default is YES)]),

=== modified file 'doc/HOWTO.xml.in'
--- doc/HOWTO.xml.in    2013-10-11 11:22:11 +0000
+++ doc/HOWTO.xml.in    2013-10-31 14:03:43 +0000
@@ -256,6 +256,82 @@
     </para>
   </section>
 
+  <section id="android">
+    <title>Android port (EXPERIMENTAL)</title>
+    <para>
+      HIPL currently has partial experimental support for the Android platform.
+      The parts that currently work are hipd, the hip daemon; and hipconf, the
+      configuration tool. Hipd does require root privileges, and your running
+      kernel must support the IPSec BEET mode, the dummy network driver and the
+      null crypto algorithm. Often one or more of these are not compiled into
+      your stock kernel, and it is likely that you need to compile and install
+      your own kernel. On our development devices we went ahead and compiled
+      the whole OS; this procedure is documented in
+      doc/hipl_android_preparation_guide.txt
+    </para>
+    <para>
+      Currently we only support compiling under linux. We provide a script in
+      tools/prepare_android_toolchain.sh that downloads and extracts the
+      toolchain needed to compile hipd and hipconf and it has been confirmed to
+      work at least on Ubuntu 12.04.
+    </para>
+    <para>
+      After HIPL source code is downloaded and the toolchain is installed, the
+      steps to compile for Android are almost similar to normal linux builds.
+      You start with autoreconf --install; then you run the configure script:
+      <programlisting>
+./configure --enable-android --disable-firewall --host=arm-linux   \
+            --prefix=/usr --sysconfdir=/etc                        \
+            CC=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-gcc  \
+            CFLAGS="-std=gnu99 -mbionic -fPIC -fno-exceptions      \
+                   --sysroot=${ANDROID_SYSROOT}"                   \
+            
LDFLAGS="-Wl,-rpath-link=${ANDROID_SYSROOT}/usr/lib,-L${ANDROID_SYSROOT}/usr/lib"
                           \
+            LIBS="-lc -lm -lgcc -lcrypto"                          \
+      </programlisting>
+      and run 'make'.
+    </para>
+    <para>
+      After the build process completes, open a root privileged shell session 
in
+      your phone and set up the environment:
+      <programlisting>
+adb root
+adb shell
+mount -o remount,rw /
+mount -o remount,rw /system
+mkdir -p /var/lock
+mkdir    /etc/hip
+ln -s /system/lib/libcrypto.so /system/lib/libcrypto.so.1.0.0
+      </programlisting>
+      After these, you can return to your normal terminal and push hipd, 
hipconf
+      and the configuration in:
+      <programlisting>
+adb push tools/hipconf  /system/xbin
+adb push hipd/hipd      /system/xbin
+adb push hipd/hipd.conf  /etc/hip
+adb push hipd/relay.conf /etc/hip
+      </programlisting>
+    </para>
+    <para>
+      On Android, hipd needs to be run with the '-a' parameter. Additionally it
+      supports the same parameters as the normal linux-version does,
+      i.e. '-k' kills an already running instance and '-b' starts hipd in the
+      background. By e.g. running 'hipd -ab' and configuring hosts in 
/etc/hosts
+      you should be able to use hip on any program that supports IPv6.
+    </para>
+    <para>
+      As the root file system on android typically resides on a ramdisk,
+      the /var/lock folder is removed every time the phone is restarted. For
+      hipd to run, it needs to be recreated by running:
+      <programlisting>
+adb root
+adb shell mount -o remount,rw /
+abd shell mkdir -p /var/lock
+      </programlisting>
+      /system and /etc typically reside in persistent storage, so anything that
+      is stored there should survive rebooting.
+    </para>
+  </section>
+
   </chapter> <!-- inst -->
 
   <chapter id="ch_prebuilt">

=== added file 'doc/hipl_android_preparation_guide.txt'
--- doc/hipl_android_preparation_guide.txt      1970-01-01 00:00:00 +0000
+++ doc/hipl_android_preparation_guide.txt      2013-10-31 14:03:43 +0000
@@ -0,0 +1,201 @@
+HIPL for Android
+================
+During the summer and early autumn I have been working on porting parts of
+HIP for Linux protocol software to Android. In it's working it relies on a
+couple of kernel features that we did not find present on most of our phones.
+These features however are readily available in the kernel source code. In this
+document I describe the steps I took to prepare a Samsung Galaxy Nexus phone to
+run HIPL. The phone should be replaceable with other Nexus family phones and
+tablets with minor changes to the examples. Preparing other phones is outside
+the scope of this document.
+
+Binary drivers for all components such as the camera may not be available and
+features that depend on them may not work. It depends on your device. You do 
+this at your own risk. At least the driver for the camera on Galaxy Nexus was 
+missing.
+
+These steps will clear the device of all personal data, so be sure to take
+backups if needed. During these steps we will unlock the device's bootloader,
+compile and install a new version of the operating system, compile a customised
+kernel for it and flash it on the device. If the features are already available
+in your current rooted rom, you don't need to do any of this.
+
+
+Android Open Source Project
+===========================
+In this guide we'll use the Android Open Source Project (AOSP) as an example.
+
+Repo -wrapper for Git
+---------------------
+AOSP uses repo for source code management.
+We need to download and install this tool first.
+
+       mkdir ~/bin
+       PATH=~/bin:$PATH
+       curl //commondatastorage.googleapis.com/git-repo-downloads/repo \
+                > ~/bin/repo
+       chmod a+x ~/bin/repo
+
+Download AOSP
+-------------
+This will download the Android Open Source Project source code. It is quite big
+and this step takes time. Consider heading to lunch after launching 'repo 
sync'.
+
+       mkdir aosp
+       cd aosp
+       repo init -u https://android.googlesource.com/platform/manifest
+       repo sync
+
+Download and unpack driver binaries
+-----------------------------------
+Drivers for many devices are proprietary and are not distributed within AOSP; 
We
+need to download them, unpack them and accept their licences. AOSP build 
process
+will search for proprietary drivers under directory 'vendor' in the source 
root.
+For the Nexus device-series the right drivers can be found at
+https://developers.google.com/android/nexus/drivers
+
+Download each driver for your device, extract them and run the scripts that
+you find inside. Each script will require you to accept a lisence and will
+extract the driver under the 'vendor' directory. After extracting them all,
+copy the 'vendor' directory to the root of your AOSP source directory.
+
+Configure
+---------
+These scripts prepare your build environment. Launching 'lunch' without
+arguments will print a menu from which you can choose your build target.
+The $OUT environment variable that we'll use later comes from here.
+
+       source build/envsetup.sh
+       lunch  full_maguro
+
+Build
+-----
+This will build the AOSP and put the result in $OUT. Adjust the number after
+-j (number of compile threads) to your liking, a good rule of thumb is the
+number of cores +1. After this step it is possible to flash the phone with the
+default AOSP system by booting your phone to bootloader and running
+'fastboot -w flashall', but now is a bit early if we want the custom kernel.
+
+       make -j4
+
+At the time of writing, there were a couple of Makefiles that would get upset 
if
+you had the environment variable NDK_ROOT set. If you encounter this,
+simply 'unset NDK_ROOT' and try again.
+
+
+Kernel
+======
+For HIPD to work, we need certain features from the kernel. These features are
+readily available but disabled by default in most Android kernels. Therefore we
+need to compile our own kernel with these features enabled.
+
+Download
+--------
+We start by downloading the kernel sources. For the Nexus series you can check
+which one you need from http://source.android.com/source/building-kernels.html.
+After cloning you can check which brances are available for checkout with
+'git branch -a'.
+
+       mkdir ../kernel
+       cd ../kernel
+       git clone https://android.googlesource.com/kernel/omap.git
+       cd omap
+       git checkout remotes/origin/android-omap-tuna-3.0-jb-mr2
+
+Configure
+---------
+We then tell the build-environment about the target architecture, add the
+compilers to PATH, load the default kernel configuration for our device and
+bring up a menu where we can do further configuration.
+
+       export ARCH=arm
+       export SUBARCH=arm
+       export CROSS_COMPILE=arm-eabi-
+       export 
PATH=$(pwd)/../../aosp/prebuilts/linux-x86/arm/arb-eabi-4.6/bin:$PATH
+       make tuna_defconfig
+       make menuconfig
+
+In the configuration menu, enable the following:
+
+- Enable loadable module support
+- Networking support > Networking options > IP: IPsec BEET mode
+- Device drivers > Network device support > Dummy net driver support
+- Cryptographic API > Null algorithms
+
+Compile
+-------
+Once the kernel has been configured, it's time to build it.
+
+       make
+
+If there are problems with "smc #0", you can try adding ".arch_extension sec" 
to
+the offending files. (I used "sed -e '1i.arch_extension sec' -i filename", it
+worked, but I'm not sure if it's the right way.)
+
+If there is a missing 'elf.h', you can copy it from under the aosp directory in
+external/elfutils/libelf/elf.h
+
+Copy to AOSP
+------------
+When the kernel has been compiled, we need a way to put it on the device. We
+replace the original AOSP kernel and put its modules in place. Make produces 
two
+symbolic links that we don't want present in the final image.
+
+       cp arch/arm/boot/zImage $OUT/kernel
+       make INSTALL_MOD_PATH=$OUT/system modules_install
+       rm $OUT/system/lib/modules/*/source
+       rm $OUT/system/lib/modules/*/build
+
+Rebuild boot image
+------------------
+Now that our kernel is in place in the AOSP tree, we need to rebuild the boot
+image with the new kernel.
+
+       cd ../../aosp
+       make bootimage
+
+
+Flash the new os to device
+==========================
+Once the new images are complete, it's time to flash them on the device. New
+images can be flashed from the bootloader ("fastboot mode"). You can generally
+get there with adb, but there is a manual way too: for the Nexus devices
+http://source.android.com/source/building-devices.html. If the device has a
+locked bootloader, it needs to be opened (usually 'fastboot oem unlock').
+(this might prevent some DRM from working!) Some of the steps might reboot the
+phone; the important part is that all the fastboot commands need to be entered
+with the device in bootloader.
+
+       adb reboot bootloader
+       fastboot oem unlock
+       fastboot reboot-bootloader
+       fastboot -w flashall
+       fastboot reboot
+
+The -w in 'fastboot -w flashall' is important. It clears caches and previous
+user data that would very likely confuse the new image and prevent it from
+booting all the way. It the phone doesn't boot this is the first thing you
+should check.
+
+Google apps (optional)
+----------------------
+Now you have a clear Android open source operating system with our customised
+kernel. This means that proprietary apps and services like Google Play and
+contacts sync are not there. The easiest way to get them there is to install a
+custom recovery image, like the Clockworkmod Recovery
+(http://clockworkmod.com/rommanager) and flash it to the device using fastboot.
+
+       adb reboot bootloader
+       fastboot flash recovery (your recovery image)
+
+Once a recovery image is installed, you can boot into recovery mode either
+straight from the bootloader menu or from normally booted Android by
+'adb reboot recovery'. The google apps can be found by searching the internet;
+e.g. from http://forum.xda-developers.com/showthread.php?p=43972031.
+
+Done
+----
+When you get here, your device should be running the Android operating system
+with our new kernel. You can verify this at "Settings > About phone". You 
should
+now have everything necessary to install HIPL.
+

=== modified file 'hipfw/hipfw.c'
--- hipfw/hipfw.c       2013-08-06 13:16:32 +0000
+++ hipfw/hipfw.c       2013-10-31 14:03:43 +0000
@@ -1931,9 +1931,11 @@
     // set up ip(6)tables rules and firewall extensions
     HIP_IFEL(firewall_init(), -1, "Firewall init failed\n");
 
+#ifndef CONFIG_HIP_ANDROID
     if (limit_capabilities) {
         HIP_IFEL(hip_set_lowcapability(), -1, "Failed to reduce privileges\n");
     }
+#endif /* CONFIG_HIP_ANDROID */
 
     highest_descriptor = hip_fw_async_sock > h4_fd ? hip_fw_async_sock : h4_fd;
     highest_descriptor = h6_fd > highest_descriptor ? h6_fd : 
highest_descriptor;

=== modified file 'libcore/builder.c'
--- libcore/builder.c   2013-10-22 12:34:28 +0000
+++ libcore/builder.c   2013-10-31 14:03:43 +0000
@@ -126,18 +126,27 @@
 static void convert_byte_order(void *content, unsigned count,
                                unsigned item_size, enum cbo_flags flag)
 {
-    uint32_t (*f32)(uint32_t) = (flag == CBO_HTON) ? htonl : ntohl;
-    uint16_t (*f16)(uint16_t) = (flag == CBO_HTON) ? htons : ntohs;
-
-    if (item_size == sizeof(uint16_t)) {
+    if (sizeof(uint16_t) == item_size) {
         uint16_t *p = content;
-        for (unsigned i = 0; i < count; i++) {
-            p[i] = f16(p[i]);
+        if (CBO_HTON == flag) {                  // 16 bit host to network
+            for (unsigned i = 0; i < count; i++) {
+                p[i] = htons(p[i]);
+            }
+        } else {                                 // 16 bit network to host
+            for (unsigned i = 0; i < count; i++) {
+                p[i] = ntohs(p[i]);
+            }
         }
-    } else if (item_size == sizeof(uint32_t)) {
+    } else {
         uint32_t *p = content;
-        for (unsigned i = 0; i < count; i++) {
-            p[i] = f32(p[i]);
+        if (CBO_HTON == flag) {                  // 32 bit host to network
+            for (unsigned i = 0; i < count; i++) {
+                p[i] = htonl(p[i]);
+            }
+        } else {                                 // 32 bit network to host
+            for (unsigned i = 0; i < count; i++) {
+                p[i] = ntohl(p[i]);
+            }
         }
     }
 }

=== modified file 'libcore/builder.h'
--- libcore/builder.h   2012-07-13 13:16:17 +0000
+++ libcore/builder.h   2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -41,6 +41,9 @@
 #include "icomm.h"
 #include "state.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
 
 /* Removed in 2.6.11 - why ? */
 extern struct hip_cert_spki_info hip_cert_spki_info;

=== modified file 'libcore/conf.c'
--- libcore/conf.c      2012-06-03 10:26:55 +0000
+++ libcore/conf.c      2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -47,6 +47,7 @@
 #define _BSD_SOURCE
 
 #include <errno.h>
+#include <inttypes.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -76,6 +77,9 @@
 #include "straddr.h"
 #include "conf.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
 
 /**
  * hipconf tool actions. These are numerical values for the first commandline

=== modified file 'libcore/filemanip.c'
--- libcore/filemanip.c 2011-10-25 21:44:47 +0000
+++ libcore/filemanip.c 2013-10-31 14:03:43 +0000
@@ -28,6 +28,7 @@
  * @brief file manipulation tools
  */
 
+#include <sys/file.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
@@ -84,7 +85,7 @@
     pid_set = read(fd, old_pid_str, sizeof(old_pid_str) - 1);
     old_pid = atoi(old_pid_str);
 
-    if (lockf(fd, F_TLOCK, 0) < 0) {
+    if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
         HIP_IFEL(!killold, -12,
                  "\nHIP daemon already running with pid %d\n"
                  "Give: -k option to kill old daemon.\n", old_pid);
@@ -93,7 +94,7 @@
                  "-k option given, terminating old one...\n", old_pid);
         /* Erase the old lock file to avoid having multiple pids
          * in the file */
-        if (lockf(fd, F_ULOCK, 0) == -1) {
+        if (flock(fd, LOCK_UN) == -1) {
             HIP_ERROR("Cannot unlock pid lock.");
         }
 
@@ -107,7 +108,7 @@
         /* Don't close file descriptor because new started process is
          * running. */
         HIP_IFEL(fd <= 0, -1, "Opening lock file failed.\n");
-        HIP_IFEL(lockf(fd, F_TLOCK, 0), -1, "Lock attempt failed.\n");
+        HIP_IFEL(flock(fd, LOCK_EX | LOCK_NB), -1, "Lock attempt failed.\n");
         if (pid_set) {
             err = kill(old_pid, SIGKILL);
         }

=== modified file 'libcore/hip_udp.h'
--- libcore/hip_udp.h   2012-05-12 06:54:33 +0000
+++ libcore/hip_udp.h   2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010, 2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -28,6 +28,12 @@
 
 #include <netinet/in.h>
 
+#include "config.h"
+
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
+
 #define HIP_NAT_UDP_PORT 10500
 
 /** For setting socket to listen for beet-udp packets. */

=== modified file 'libcore/protodefs.h'
--- libcore/protodefs.h 2012-07-20 07:52:59 +0000
+++ libcore/protodefs.h 2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -37,9 +37,14 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 
+#include "config.h"
 #include "esp_prot_common.h"
 #include "hashchain.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
+
 #ifndef PF_HIP
 #define PF_HIP 32
 #endif

=== modified file 'libcore/state.h'
--- libcore/state.h     2012-06-03 10:26:55 +0000
+++ libcore/state.h     2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -43,6 +43,10 @@
 #include "protodefs.h"
 #include "statistics.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
+
 #define HIP_ENDPOINT_FLAG_PUBKEY           0
 #define HIP_ENDPOINT_FLAG_HIT              1
 #define HIP_ENDPOINT_FLAG_ANON             2

=== modified file 'libhipl/hipd.c'
--- libhipl/hipd.c      2012-05-12 10:21:32 +0000
+++ libhipl/hipd.c      2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -34,6 +34,7 @@
 #define _BSD_SOURCE
 
 #include <errno.h>
+#include <inttypes.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -67,6 +68,9 @@
 #include "netdev.h"
 #include "hipd.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
 
 /** For receiving netlink IPsec events (acquire, expire, etc) */
 struct rtnl_handle hip_nl_ipsec;

=== modified file 'libhipl/init.c'
--- libhipl/init.c      2013-10-22 19:16:18 +0000
+++ libhipl/init.c      2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -94,6 +94,9 @@
 #include "user.h"
 #include "init.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
 
 /**
  * HIP daemon lock file is used to prevent multiple instances
@@ -1276,9 +1279,11 @@
     }
 #endif
 
+#ifndef CONFIG_HIP_ANDROID
     if (flags & HIPD_START_LOWCAP) {
         HIP_IFEL(hip_set_lowcapability(), -1, "Failed to set capabilities\n");
     }
+#endif /* CONFIG_HIP_ANDROID */
 
     if (hip_get_nsupdate_status()) {
         nsupdate(1);

=== modified file 'libhipl/maintenance.c'
--- libhipl/maintenance.c       2012-05-12 10:21:32 +0000
+++ libhipl/maintenance.c       2013-10-31 14:03:43 +0000
@@ -41,6 +41,7 @@
 
 #include <arpa/inet.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>

=== modified file 'libhipl/netdev.c'
--- libhipl/netdev.c    2012-07-28 21:18:08 +0000
+++ libhipl/netdev.c    2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -54,6 +54,11 @@
 #include <sys/ioctl.h>
 #include <linux/rtnetlink.h>
 
+/* Needed for in6_addr on android but conflicts with netinet/in.h on linux */
+#ifdef CONFIG_HIP_ANDROID
+#include <linux/in6.h>
+#endif /* CONFIG_HIP_ANDROID */
+
 #include "libcore/builder.h"
 #include "libcore/common.h"
 #include "libcore/conf.h"
@@ -343,7 +348,7 @@
     list_for_each_safe(tmp, t, addresses, c) {
         n = list_entry(tmp);
 
-        if (IN6_IS_ADDR_V4MAPPED(hip_cast_sa_addr((struct sockaddr *) 
&n->addr)) == mapped) {
+        if (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *) 
hip_cast_sa_addr((struct sockaddr *) &n->addr)) == mapped) {
             return 1;
         }
     }

=== modified file 'modules/heartbeat/hipd/heartbeat.c'
--- modules/heartbeat/hipd/heartbeat.c  2012-05-12 10:21:32 +0000
+++ modules/heartbeat/hipd/heartbeat.c  2013-10-31 14:03:43 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012 Aalto University and RWTH Aachen University.
+ * Copyright (c) 2010, 2012-2013 Aalto University and RWTH Aachen University.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -86,6 +86,10 @@
 #include "libhipl/user.h"
 #include "heartbeat.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
+
 #define HIP_MAX_ICMP_PACKET 512
 
 static int hip_icmp_sock;

=== modified file 'test/performance/fw_port_bindings_performance.c'
--- test/performance/fw_port_bindings_performance.c     2012-03-13 15:00:27 
+0000
+++ test/performance/fw_port_bindings_performance.c     2013-10-31 14:03:43 
+0000
@@ -31,6 +31,10 @@
 #include "hipfw/line_parser.h"
 #include "hipfw/port_bindings.h"
 
+#ifdef CONFIG_HIP_ANDROID
+#include "android/android.h"
+#endif /* CONFIG_HIP_ANDROID */
+
 static double time_clock(const unsigned int iterations)
 {
     clock_t      start, end;

=== added file 'tools/prepare_android_toolchain.sh'
--- tools/prepare_android_toolchain.sh  1970-01-01 00:00:00 +0000
+++ tools/prepare_android_toolchain.sh  2013-10-31 14:03:43 +0000
@@ -0,0 +1,174 @@
+# Script is for building an Android cross-compilation environment on linux.
+
+# If you want to change the install folder, do it here.
+TOOLCHAIN_INSTALL_FOLDER=${HOME}/android_tools
+OPENSSL_VERSION='1.0.1e'
+NDK_VERSION=r9
+SYSTEM=linux-x86_64
+
+# These are for the script's internals
+NDK_PACKAGE=android-ndk-${NDK_VERSION}-${SYSTEM}
+NDK_ROOT=${TOOLCHAIN_INSTALL_FOLDER}/android-ndk-${NDK_VERSION}
+ANDROID_TOOLCHAIN=${TOOLCHAIN_INSTALL_FOLDER}/toolchain
+ANDROID_SYSROOT=${ANDROID_TOOLCHAIN}/sysroot
+
+# Functions
+make_install_folder()
+{
+    if [ ! -d ${TOOLCHAIN_INSTALL_FOLDER} ]; then
+        if ! mkdir -p ${TOOLCHAIN_INSTALL_FOLDER}; then
+            echo "Install failed. Could not create folder for toolchain."
+            exit
+        fi
+    fi
+}
+
+insert_vars_to_bashrc()
+{
+    echo "Inserting the following to .bashrc"
+    echo "export NDK_ROOT=${NDK_ROOT}"
+    echo "export ANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN}"
+    echo "export ANDROID_SYSROOT=${ANDROID_SYSROOT}"
+
+    if ! grep ~/.bashrc -q -e "NDK_ROOT"; then
+        echo "export NDK_ROOT=${NDK_ROOT}" >> ${HOME}/.bashrc
+    fi
+    if ! grep ~/.bashrc -q -e "ANDROID_TOOLCHAIN"; then
+        echo "export ANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN}" >> ${HOME}/.bashrc
+    fi
+    if ! grep ~/.bashrc -q -e "ANDROID_SYSROOT"; then
+        echo "export ANDROID_SYSROOT=${ANDROID_SYSROOT}" >> ${HOME}/.bashrc
+    fi
+}
+
+get_android_ndk()
+{
+    # If NDK is not found, download and install
+    if [ ! -d ${NDK_ROOT} ]; then
+        echo "Android NDK not found."
+        if [ ! -f ${NDK_PACKAGE}.tar.bz2 ]; then
+            echo "Android NDK package not found, downloading.."
+            wget http://dl.google.com/android/ndk/${NDK_PACKAGE}.tar.bz2
+        else
+            echo "Android NDK package found, using that."
+        fi
+        echo "Extracting Android NDK.."
+        tar xf ${NDK_PACKAGE}.tar.bz2
+    else
+    echo "Android NDK found, using that."
+    fi
+}
+
+get_openssl()
+{
+    # If OpenSSL sources are not found, download them
+    if [ ! -d openssl-${OPENSSL_VERSION} ]; then
+        echo "OpenSSL source not found."
+        if [ ! -f openssl-${OPENSSL_VERSION}.tar.gz ]; then
+            echo "OpenSSL source package not found, downloading.."
+            wget 
http://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
+        else
+            echo "OpenSSL source package found, using that."
+        fi
+        echo "Extracting OpenSSL source.."
+        tar xf openssl-${OPENSSL_VERSION}.tar.gz
+    else
+        echo "OpenSSL source found, using that."
+    fi
+}
+
+build_ndk_toolchain()
+{
+    echo "Building Android standalone toolchain."
+    ${NDK_ROOT}/build/tools/make-standalone-toolchain.sh \
+    --toolchain=arm-linux-androideabi-4.6 \
+    --platform=android-9 \
+    --arch=arm \
+    --ndk-dir=${NDK_ROOT} \
+    --system=${SYSTEM} \
+    --install-dir=${ANDROID_TOOLCHAIN}
+}
+
+build_openssl()
+{
+    # Configure and install OpenSSL in the toolchain
+    cd ${TOOLCHAIN_INSTALL_FOLDER}/openssl-${OPENSSL_VERSION}
+    ./config no-asm shared --prefix=${ANDROID_SYSROOT}/usr
+    sed 's/-m64//g' -i Makefile    # The arm compiler doesn't support -m64
+    make install
+    cd ${TOOLCHAIN_INSTALL_FOLDER}
+}
+
+set_openssl_build_env_vars()
+{
+    export CC=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-gcc
+    export AR=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ar r
+    export RANLIB=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ranlib
+    export NM=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-nm
+    export CFLAG="-DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H  \
+                  -DOPENSSL_N -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer   \
+                  -Wall -fPIC"
+    export PLATFORM="arm-linux"
+}
+
+print_instructions()
+{
+    # Print instructions
+    echo ""
+    echo ""
+    echo "The tools are now installed under $TOOLCHAIN_INSTALL_FOLDER"
+    echo ""
+    echo "Please run these commands now:"
+    echo "export NDK_ROOT=${NDK_ROOT}"
+    echo "export ANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN}"
+    echo "export ANDROID_SYSROOT=${ANDROID_SYSROOT}"
+    echo ""
+    echo "We also recommend adding them to ${HOME}/.bashrc"
+    echo "so they will be ready for future builds."
+    echo ""
+    echo "Then in HIPL root run: "\
+           ./configure        \
+           --enable-android   \
+           --disable-firewall \
+           --host=arm-linux   \
+           --prefix=/usr      \
+           --sysconfdir=/etc  \
+           CC=\${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-gcc \
+                                                                  \
+           CFLAGS=\"-std=gnu99 -mbionic -fPIC -fno-exceptions     \
+                    --sysroot=\${ANDROID_SYSROOT}\"               \
+                                                                  \
+           
LDFLAGS=\"-Wl,-rpath-link=\${ANDROID_SYSROOT}/usr/lib,-L\${ANDROID_SYSROOT}/usr/lib\"
 \
+                                                                  \
+           LIBS=\"-lc -lm -lgcc -lcrypto\"
+
+    # It is important that there are no spaces after commas in LDFLAGS.
+}
+
+print_invocation_help()
+{
+    echo "Invocation: $0 [--auto-insert-bashrc]"
+    echo "--auto-insert-bashrc  adds the NDK toolchain paths to .bashrc 
automatically."
+}
+
+# Main script
+if [ ! "${1}xxx" = "xxx" ]; then
+    if [ "$1" = "--auto-insert-bashrc" ]; then
+        insert_vars_to_bashrc
+    else
+        print_invocation_help
+        exit
+    fi # if --auto-insert-bashrc
+fi # if $1 defined
+
+make_install_folder
+cd ${TOOLCHAIN_INSTALL_FOLDER}
+
+get_android_ndk
+build_ndk_toolchain
+
+get_openssl
+set_openssl_build_env_vars
+build_openssl
+
+print_instructions

Other related posts: