summaryrefslogtreecommitdiffstats
path: root/luni/src/main
diff options
context:
space:
mode:
authorErik Kline <ek@google.com>2015-03-10 22:04:27 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-03-10 22:04:27 +0000
commitb186e3c9195112f7acf938be388889dd773c2b18 (patch)
tree117e14d5da80d8e3cd6f2afcba5b8eacee303eed /luni/src/main
parent2e1d4fcc089f4d3451e9c982e7b192143df37674 (diff)
parent24c68680f1c187fa9d2a9cc4c4ddb5ae09fa7dfb (diff)
downloadlibcore-b186e3c9195112f7acf938be388889dd773c2b18.zip
libcore-b186e3c9195112f7acf938be388889dd773c2b18.tar.gz
libcore-b186e3c9195112f7acf938be388889dd773c2b18.tar.bz2
am 24c68680: am 649f614e: am 2882e512: Merge "Add support for netlink sockets and addresses."
* commit '24c68680f1c187fa9d2a9cc4c4ddb5ae09fa7dfb': Add support for netlink sockets and addresses.
Diffstat (limited to 'luni/src/main')
-rw-r--r--luni/src/main/java/android/system/NetlinkSocketAddress.java61
-rw-r--r--luni/src/main/java/android/system/Os.java4
-rw-r--r--luni/src/main/java/android/system/OsConstants.java15
-rw-r--r--luni/src/main/java/libcore/io/ForwardingOs.java2
-rw-r--r--luni/src/main/java/libcore/io/Os.java2
-rw-r--r--luni/src/main/java/libcore/io/Posix.java2
-rw-r--r--luni/src/main/native/android_system_OsConstants.cpp15
-rw-r--r--luni/src/main/native/libcore_io_Posix.cpp102
8 files changed, 195 insertions, 8 deletions
diff --git a/luni/src/main/java/android/system/NetlinkSocketAddress.java b/luni/src/main/java/android/system/NetlinkSocketAddress.java
new file mode 100644
index 0000000..af78cd0
--- /dev/null
+++ b/luni/src/main/java/android/system/NetlinkSocketAddress.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+package android.system;
+
+import libcore.util.Objects;
+import java.net.SocketAddress;
+
+/**
+ * Netlink socket address.
+ *
+ * Corresponds to Linux's {@code struct sockaddr_nl} from
+ * <a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/netlink.h">&lt;linux/netlink.h&gt;</a>.
+ *
+ * @hide
+ */
+public final class NetlinkSocketAddress extends SocketAddress {
+ /** port ID */
+ private final int nlPortId;
+
+ /** multicast groups mask */
+ private final int nlGroupsMask;
+
+ public NetlinkSocketAddress() {
+ this(0, 0);
+ }
+
+ public NetlinkSocketAddress(int nlPortId) {
+ this(nlPortId, 0);
+ }
+
+ public NetlinkSocketAddress(int nlPortId, int nlGroupsMask) {
+ this.nlPortId = nlPortId;
+ this.nlGroupsMask = nlGroupsMask;
+ }
+
+ public int getPortId() {
+ return nlPortId;
+ }
+
+ public int getGroupsMask() {
+ return nlGroupsMask;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index 8028f23..ee683d2 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -54,6 +54,8 @@ public final class Os {
*/
public static void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.bind(fd, address, port); }
+ /** @hide */ public static void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.bind(fd, address); }
+
/**
* See <a href="http://man7.org/linux/man-pages/man2/chmod.2.html">chmod(2)</a>.
*/
@@ -74,6 +76,8 @@ public final class Os {
*/
public static void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { Libcore.os.connect(fd, address, port); }
+ /** @hide */ public static void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.connect(fd, address); }
+
/**
* See <a href="http://man7.org/linux/man-pages/man2/dup.2.html">dup(2)</a>.
*/
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 1f9205c..a52004b 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -95,6 +95,7 @@ public final class OsConstants {
public static final int AF_INET = placeholder();
public static final int AF_INET6 = placeholder();
+ /** @hide */ public static final int AF_NETLINK = placeholder();
public static final int AF_UNIX = placeholder();
public static final int AF_UNSPEC = placeholder();
public static final int AI_ADDRCONFIG = placeholder();
@@ -324,6 +325,7 @@ public final class OsConstants {
public static final int MS_ASYNC = placeholder();
public static final int MS_INVALIDATE = placeholder();
public static final int MS_SYNC = placeholder();
+ /** @hide */ public static final int NETLINK_ROUTE = placeholder();
public static final int NI_DGRAM = placeholder();
public static final int NI_NAMEREQD = placeholder();
public static final int NI_NOFQDN = placeholder();
@@ -365,6 +367,19 @@ public final class OsConstants {
public static final int RT_SCOPE_NOWHERE = placeholder();
public static final int RT_SCOPE_SITE = placeholder();
public static final int RT_SCOPE_UNIVERSE = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV4_IFADDR = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV4_MROUTE = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV4_ROUTE = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV4_RULE = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV6_IFADDR = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV6_IFINFO = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV6_MROUTE = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV6_PREFIX = placeholder();
+ /** @hide */ public static final int RTMGRP_IPV6_ROUTE = placeholder();
+ /** @hide */ public static final int RTMGRP_LINK = placeholder();
+ /** @hide */ public static final int RTMGRP_NEIGH = placeholder();
+ /** @hide */ public static final int RTMGRP_NOTIFY = placeholder();
+ /** @hide */ public static final int RTMGRP_TC = placeholder();
public static final int SEEK_CUR = placeholder();
public static final int SEEK_END = placeholder();
public static final int SEEK_SET = placeholder();
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index 5c90757..d07b99a 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -54,10 +54,12 @@ public class ForwardingOs implements Os {
public boolean access(String path, int mode) throws ErrnoException { return os.access(path, mode); }
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return os.android_getaddrinfo(node, hints, netId); }
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
+ public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.bind(fd, address); }
public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
public void chown(String path, int uid, int gid) throws ErrnoException { os.chown(path, uid, gid); }
public void close(FileDescriptor fd) throws ErrnoException { os.close(fd); }
public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.connect(fd, address, port); }
+ public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.connect(fd, address); }
public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException { return os.dup(oldFd); }
public FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException { return os.dup2(oldFd, newFd); }
public String[] environ() { return os.environ(); }
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 620af19..3fc031c 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -45,10 +45,12 @@ public interface Os {
public boolean access(String path, int mode) throws ErrnoException;
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
+ public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
public void chmod(String path, int mode) throws ErrnoException;
public void chown(String path, int uid, int gid) throws ErrnoException;
public void close(FileDescriptor fd) throws ErrnoException;
public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
+ public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException;
public FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException;
public String[] environ();
diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java
index 2629553..251d06f 100644
--- a/luni/src/main/java/libcore/io/Posix.java
+++ b/luni/src/main/java/libcore/io/Posix.java
@@ -48,10 +48,12 @@ public final class Posix implements Os {
public native boolean access(String path, int mode) throws ErrnoException;
public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
+ public native void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
public native void chmod(String path, int mode) throws ErrnoException;
public native void chown(String path, int uid, int gid) throws ErrnoException;
public native void close(FileDescriptor fd) throws ErrnoException;
public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
+ public native void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
public native FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException;
public native FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException;
public native String[] environ();
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 46dabb3..0c55305 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -58,6 +58,7 @@ static void initConstant(JNIEnv* env, jclass c, const char* fieldName, int value
static void OsConstants_initConstants(JNIEnv* env, jclass c) {
initConstant(env, c, "AF_INET", AF_INET);
initConstant(env, c, "AF_INET6", AF_INET6);
+ initConstant(env, c, "AF_NETLINK", AF_NETLINK);
initConstant(env, c, "AF_UNIX", AF_UNIX);
initConstant(env, c, "AF_UNSPEC", AF_UNSPEC);
initConstant(env, c, "AI_ADDRCONFIG", AI_ADDRCONFIG);
@@ -355,6 +356,7 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) {
initConstant(env, c, "MS_ASYNC", MS_ASYNC);
initConstant(env, c, "MS_INVALIDATE", MS_INVALIDATE);
initConstant(env, c, "MS_SYNC", MS_SYNC);
+ initConstant(env, c, "NETLINK_ROUTE", NETLINK_ROUTE);
initConstant(env, c, "NI_DGRAM", NI_DGRAM);
initConstant(env, c, "NI_NAMEREQD", NI_NAMEREQD);
initConstant(env, c, "NI_NOFQDN", NI_NOFQDN);
@@ -407,6 +409,19 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) {
initConstant(env, c, "RT_SCOPE_NOWHERE", RT_SCOPE_NOWHERE);
initConstant(env, c, "RT_SCOPE_SITE", RT_SCOPE_SITE);
initConstant(env, c, "RT_SCOPE_UNIVERSE", RT_SCOPE_UNIVERSE);
+ initConstant(env, c, "RTMGRP_IPV4_IFADDR", RTMGRP_IPV4_IFADDR);
+ initConstant(env, c, "RTMGRP_IPV4_MROUTE", RTMGRP_IPV4_MROUTE);
+ initConstant(env, c, "RTMGRP_IPV4_ROUTE", RTMGRP_IPV4_ROUTE);
+ initConstant(env, c, "RTMGRP_IPV4_RULE", RTMGRP_IPV4_RULE);
+ initConstant(env, c, "RTMGRP_IPV6_IFADDR", RTMGRP_IPV6_IFADDR);
+ initConstant(env, c, "RTMGRP_IPV6_IFINFO", RTMGRP_IPV6_IFINFO);
+ initConstant(env, c, "RTMGRP_IPV6_MROUTE", RTMGRP_IPV6_MROUTE);
+ initConstant(env, c, "RTMGRP_IPV6_PREFIX", RTMGRP_IPV6_PREFIX);
+ initConstant(env, c, "RTMGRP_IPV6_ROUTE", RTMGRP_IPV6_ROUTE);
+ initConstant(env, c, "RTMGRP_LINK", RTMGRP_LINK);
+ initConstant(env, c, "RTMGRP_NEIGH", RTMGRP_NEIGH);
+ initConstant(env, c, "RTMGRP_NOTIFY", RTMGRP_NOTIFY);
+ initConstant(env, c, "RTMGRP_TC", RTMGRP_TC);
#endif
initConstant(env, c, "SEEK_CUR", SEEK_CUR);
initConstant(env, c, "SEEK_END", SEEK_END);
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index 4c7e372..a1113ab 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -34,6 +34,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
+#include <linux/rtnetlink.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -266,14 +267,25 @@ private:
};
static jobject makeSocketAddress(JNIEnv* env, const sockaddr_storage& ss) {
- jint port;
- jobject inetAddress = sockaddrToInetAddress(env, ss, &port);
- if (inetAddress == NULL) {
- return NULL;
- }
- static jmethodID ctor = env->GetMethodID(JniConstants::inetSocketAddressClass, "<init>",
- "(Ljava/net/InetAddress;I)V");
- return env->NewObject(JniConstants::inetSocketAddressClass, ctor, inetAddress, port);
+ if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6 || ss.ss_family == AF_UNIX) {
+ jint port;
+ jobject inetAddress = sockaddrToInetAddress(env, ss, &port);
+ if (inetAddress == NULL) {
+ return NULL; // Exception already thrown.
+ }
+ static jmethodID ctor = env->GetMethodID(JniConstants::inetSocketAddressClass,
+ "<init>", "(Ljava/net/InetAddress;I)V");
+ return env->NewObject(JniConstants::inetSocketAddressClass, ctor, inetAddress, port);
+ } else if (ss.ss_family == AF_NETLINK) {
+ const struct sockaddr_nl* nl_addr = reinterpret_cast<const struct sockaddr_nl*>(&ss);
+ static jmethodID ctor = env->GetMethodID(JniConstants::netlinkSocketAddressClass,
+ "<init>", "(II)V");
+ return env->NewObject(JniConstants::netlinkSocketAddressClass, ctor,
+ static_cast<jint>(nl_addr->nl_pid),
+ static_cast<jint>(nl_addr->nl_groups));
+ }
+ jniThrowException(env, "java/lang/IllegalArgumentException", "unsupported ss_family");
+ return NULL;
}
static jobject makeStructPasswd(JNIEnv* env, const struct passwd& pw) {
@@ -384,6 +396,49 @@ static bool fillInetSocketAddress(JNIEnv* env, jint rc, jobject javaInetSocketAd
return true;
}
+static bool javaInetSocketAddressToSockaddr(
+ JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
+ static jfieldID addressFid = env->GetFieldID(
+ JniConstants::inetSocketAddressClass, "addr", "Ljava/net/InetAddress;");
+ static jfieldID portFid = env->GetFieldID(JniConstants::inetSocketAddressClass, "port", "I");
+ return inetAddressToSockaddr(env,
+ env->GetObjectField(javaSocketAddress, addressFid),
+ env->GetIntField(javaSocketAddress, portFid),
+ ss, sa_len);
+}
+
+static bool javaNetlinkSocketAddressToSockaddr(
+ JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
+ static jfieldID nlPidFid = env->GetFieldID(
+ JniConstants::netlinkSocketAddressClass, "nlPortId", "I");
+ static jfieldID nlGroupsFid = env->GetFieldID(
+ JniConstants::netlinkSocketAddressClass, "nlGroupsMask", "I");
+
+ sockaddr_nl *nlAddr = reinterpret_cast<sockaddr_nl *>(&ss);
+ nlAddr->nl_family = AF_NETLINK;
+ nlAddr->nl_pid = env->GetIntField(javaSocketAddress, nlPidFid);
+ nlAddr->nl_groups = env->GetIntField(javaSocketAddress, nlGroupsFid);
+ sa_len = sizeof(sockaddr_nl);
+ return true;
+}
+
+static bool javaSocketAddressToSockaddr(
+ JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
+ if (javaSocketAddress == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return false;
+ }
+
+ if (env->IsInstanceOf(javaSocketAddress, JniConstants::netlinkSocketAddressClass)) {
+ return javaNetlinkSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
+ } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
+ return javaInetSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
+ }
+ jniThrowException(env, "java/lang/UnsupportedOperationException",
+ "unsupported SocketAddress subclass");
+ return false;
+}
+
static jobject doStat(JNIEnv* env, jstring javaPath, bool isLstat) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
@@ -487,6 +542,19 @@ static void Posix_bind(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress
(void) NET_FAILURE_RETRY(env, int, bind, javaFd, sa, sa_len);
}
+static void Posix_bindSocketAddress(
+ JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
+ sockaddr_storage ss;
+ socklen_t sa_len;
+ if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
+ return; // Exception already thrown.
+ }
+
+ const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss);
+ // We don't need the return value because we'll already have thrown.
+ (void) NET_FAILURE_RETRY(env, int, bind, javaFd, sa, sa_len);
+}
+
static void Posix_chmod(JNIEnv* env, jobject, jstring javaPath, jint mode) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
@@ -526,6 +594,19 @@ static void Posix_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddr
(void) NET_FAILURE_RETRY(env, int, connect, javaFd, sa, sa_len);
}
+static void Posix_connectSocketAddress(
+ JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
+ sockaddr_storage ss;
+ socklen_t sa_len;
+ if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) {
+ return; // Exception already thrown.
+ }
+
+ const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss);
+ // We don't need the return value because we'll already have thrown.
+ (void) NET_FAILURE_RETRY(env, int, connect, javaFd, sa, sa_len);
+}
+
static jobject Posix_dup(JNIEnv* env, jobject, jobject javaOldFd) {
int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
int newFd = throwIfMinusOne(env, "dup", TEMP_FAILURE_RETRY(dup(oldFd)));
@@ -1587,15 +1668,20 @@ static jint Posix_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buff
return IO_FAILURE_RETRY(env, ssize_t, writev, javaFd, ioVec.get(), ioVec.size());
}
+#define NATIVE_METHOD_OVERLOAD(className, functionName, signature, variant) \
+ { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName ## variant) }
+
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/InetSocketAddress;)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"),
NATIVE_METHOD(Posix, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
+ NATIVE_METHOD_OVERLOAD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
NATIVE_METHOD(Posix, chmod, "(Ljava/lang/String;I)V"),
NATIVE_METHOD(Posix, chown, "(Ljava/lang/String;II)V"),
NATIVE_METHOD(Posix, close, "(Ljava/io/FileDescriptor;)V"),
NATIVE_METHOD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
+ NATIVE_METHOD_OVERLOAD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
NATIVE_METHOD(Posix, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, environ, "()[Ljava/lang/String;"),