Loading core/java/android/net/NetworkUtils.java +8 −1 Original line number Diff line number Diff line Loading @@ -45,12 +45,19 @@ public class NetworkUtils { public native static void attachDhcpFilter(FileDescriptor fd) throws SocketException; /** * Attaches a socket filter that accepts ICMP6 router advertisement packets to the given socket. * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket. * @param fd the socket's {@link FileDescriptor}. * @param packetType the hardware address type, one of ARPHRD_*. */ public native static void attachRaFilter(FileDescriptor fd, int packetType) throws SocketException; /** * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements. * @param fd the socket's {@link FileDescriptor}. * @param ifIndex the interface index. */ public native static void setupRaSocket(FileDescriptor fd, int ifIndex) throws SocketException; /** * Binds the current process to the network designated by {@code netId}. All sockets created * in the future (and not explicitly bound via a bound {@link SocketFactory} (see Loading core/jni/android_net_NetUtils.cpp +94 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,99 @@ static void android_net_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobject } } static void android_net_utils_setupRaSocket(JNIEnv *env, jobject clazz, jobject javaFd, jint ifIndex) { static const int kLinkLocalHopLimit = 255; int fd = jniGetFDFromFileDescriptor(env, javaFd); // Set an ICMPv6 filter that only passes Router Solicitations. struct icmp6_filter rs_only; ICMP6_FILTER_SETBLOCKALL(&rs_only); ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only); socklen_t len = sizeof(rs_only); if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(ICMP6_FILTER): %s", strerror(errno)); return; } // Most/all of the rest of these options can be set via Java code, but // because we're here on account of setting an icmp6_filter go ahead // and do it all natively for now. // // TODO: Consider moving these out to Java. // Set the multicast hoplimit to 255 (link-local only). int hops = kLinkLocalHopLimit; len = sizeof(hops); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno)); return; } // Set the unicast hoplimit to 255 (link-local only). hops = kLinkLocalHopLimit; len = sizeof(hops); if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno)); return; } // Explicitly disable multicast loopback. int off = 0; len = sizeof(off); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno)); return; } // Specify the IPv6 interface to use for outbound multicast. len = sizeof(ifIndex); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno)); return; } // Additional options to be considered: // - IPV6_TCLASS // - IPV6_RECVPKTINFO // - IPV6_RECVHOPLIMIT // Bind to [::]. const struct sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_port = 0, .sin6_flowinfo = 0, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_scope_id = 0, }; auto sa = reinterpret_cast<const struct sockaddr *>(&sin6); len = sizeof(sin6); if (bind(fd, sa, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "bind(IN6ADDR_ANY): %s", strerror(errno)); return; } // Join the all-routers multicast group, ff02::2%index. struct ipv6_mreq all_rtrs = { .ipv6mr_multiaddr = {{{0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}}, .ipv6mr_interface = ifIndex, }; len = sizeof(all_rtrs); if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno)); return; } } static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId) { return (jboolean) !setNetworkForProcess(netId); Loading Loading @@ -170,6 +263,7 @@ static const JNINativeMethod gNetworkUtilMethods[] = { { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess }, { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter }, { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachRaFilter }, { "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_setupRaSocket }, }; int register_android_net_NetworkUtils(JNIEnv* env) Loading services/net/java/android/net/ip/RouterAdvertisementDaemon.java 0 → 100644 +581 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/net/NetworkUtils.java +8 −1 Original line number Diff line number Diff line Loading @@ -45,12 +45,19 @@ public class NetworkUtils { public native static void attachDhcpFilter(FileDescriptor fd) throws SocketException; /** * Attaches a socket filter that accepts ICMP6 router advertisement packets to the given socket. * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket. * @param fd the socket's {@link FileDescriptor}. * @param packetType the hardware address type, one of ARPHRD_*. */ public native static void attachRaFilter(FileDescriptor fd, int packetType) throws SocketException; /** * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements. * @param fd the socket's {@link FileDescriptor}. * @param ifIndex the interface index. */ public native static void setupRaSocket(FileDescriptor fd, int ifIndex) throws SocketException; /** * Binds the current process to the network designated by {@code netId}. All sockets created * in the future (and not explicitly bound via a bound {@link SocketFactory} (see Loading
core/jni/android_net_NetUtils.cpp +94 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,99 @@ static void android_net_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobject } } static void android_net_utils_setupRaSocket(JNIEnv *env, jobject clazz, jobject javaFd, jint ifIndex) { static const int kLinkLocalHopLimit = 255; int fd = jniGetFDFromFileDescriptor(env, javaFd); // Set an ICMPv6 filter that only passes Router Solicitations. struct icmp6_filter rs_only; ICMP6_FILTER_SETBLOCKALL(&rs_only); ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &rs_only); socklen_t len = sizeof(rs_only); if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &rs_only, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(ICMP6_FILTER): %s", strerror(errno)); return; } // Most/all of the rest of these options can be set via Java code, but // because we're here on account of setting an icmp6_filter go ahead // and do it all natively for now. // // TODO: Consider moving these out to Java. // Set the multicast hoplimit to 255 (link-local only). int hops = kLinkLocalHopLimit; len = sizeof(hops); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno)); return; } // Set the unicast hoplimit to 255 (link-local only). hops = kLinkLocalHopLimit; len = sizeof(hops); if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno)); return; } // Explicitly disable multicast loopback. int off = 0; len = sizeof(off); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_MULTICAST_LOOP): %s", strerror(errno)); return; } // Specify the IPv6 interface to use for outbound multicast. len = sizeof(ifIndex); if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_MULTICAST_IF): %s", strerror(errno)); return; } // Additional options to be considered: // - IPV6_TCLASS // - IPV6_RECVPKTINFO // - IPV6_RECVHOPLIMIT // Bind to [::]. const struct sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_port = 0, .sin6_flowinfo = 0, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_scope_id = 0, }; auto sa = reinterpret_cast<const struct sockaddr *>(&sin6); len = sizeof(sin6); if (bind(fd, sa, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "bind(IN6ADDR_ANY): %s", strerror(errno)); return; } // Join the all-routers multicast group, ff02::2%index. struct ipv6_mreq all_rtrs = { .ipv6mr_multiaddr = {{{0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}}, .ipv6mr_interface = ifIndex, }; len = sizeof(all_rtrs); if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &all_rtrs, len) != 0) { jniThrowExceptionFmt(env, "java/net/SocketException", "setsockopt(IPV6_JOIN_GROUP): %s", strerror(errno)); return; } } static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId) { return (jboolean) !setNetworkForProcess(netId); Loading Loading @@ -170,6 +263,7 @@ static const JNINativeMethod gNetworkUtilMethods[] = { { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess }, { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter }, { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachRaFilter }, { "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_setupRaSocket }, }; int register_android_net_NetworkUtils(JNIEnv* env) Loading
services/net/java/android/net/ip/RouterAdvertisementDaemon.java 0 → 100644 +581 −0 File added.Preview size limit exceeded, changes collapsed. Show changes