--- /dev/null 2020-01-06 11:04:45.000000000 +0000 +++ new/src/java.base/share/native/libnio/ch/nio_multicast.c 2020-01-06 11:04:45.000000000 +0000 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include + +#include "nio_multicast.h" + +#define COPY_INET6_ADDRESS(env, source, target) \ + (*env)->GetByteArrayRegion(env, source, 0, 16, target) + +/** + * Initialize a group_req structure with the given interface index and IPv4 + * multicast group. + */ +void initGroupReq4(JNIEnv* env, struct group_req *req, jint index, jint group) +{ + struct sockaddr_in* sin; + +#ifdef WIN32 + req->gr_interface = (ULONG)index; +#else + req->gr_interface = (uint32_t)index; +#endif + + sin = (struct sockaddr_in*)&(req->gr_group); + memset(sin, 0, sizeof(struct sockaddr_in)); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl(group); +} + +/** + * Initialize a group_source_req structure with the given interface index, IPv4 + * multicast group, and IPv4 source address. + */ +void initGroupSourceReq4(JNIEnv* env, struct group_source_req *req, + jint index, jint group, jint source) +{ + struct sockaddr_in* sin; + +#ifdef WIN32 + req->gsr_interface = (ULONG)index; +#else + req->gsr_interface = (uint32_t)index; +#endif + + sin = (struct sockaddr_in*)&(req->gsr_group); + memset(sin, 0, sizeof(struct sockaddr_in)); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl(group); + + sin = (struct sockaddr_in*)&(req->gsr_source); + memset(sin, 0, sizeof(struct sockaddr_in)); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl(source); +} + +/** + * Initialize a group_req structure with the given interface index and IPv6 + * multicast group. + */ +void initGroupReq6(JNIEnv* env, struct group_req *req, jint index, jbyteArray group) +{ + struct sockaddr_in6* sin6; + +#ifdef WIN32 + req->gr_interface = (ULONG)index; +#else + req->gr_interface = (uint32_t)index; +#endif + + sin6 = (struct sockaddr_in6*)&(req->gr_group); + memset(sin6, 0, sizeof(struct sockaddr_in6)); + sin6->sin6_family = AF_INET6; + COPY_INET6_ADDRESS(env, group, (jbyte*)&(sin6->sin6_addr)); +} + +/** + * Initialize a group_source req structure with the given interface index, IPv6 + * multicast group, and IPv6 source address. + */ +void initGroupSourceReq6(JNIEnv* env, struct group_source_req *req, + int index, jbyteArray group, jbyteArray source) +{ + struct sockaddr_in6* sin6; + +#ifdef WIN32 + req->gsr_interface = (ULONG)index; +#else + req->gsr_interface = (uint32_t)index; +#endif + + sin6 = (struct sockaddr_in6*)&(req->gsr_group); + memset(sin6, 0, sizeof(struct sockaddr_in6)); + sin6->sin6_family = AF_INET6; + COPY_INET6_ADDRESS(env, group, (jbyte*)&(sin6->sin6_addr)); + + sin6 = (struct sockaddr_in6*)&(req->gsr_source); + memset(sin6, 0, sizeof(struct sockaddr_in6)); + sin6->sin6_family = AF_INET6; + COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr)); +}