1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <string.h> 27 28 #include "nio_multicast.h" 29 30 #define COPY_INET6_ADDRESS(env, source, target) \ 31 (*env)->GetByteArrayRegion(env, source, 0, 16, target) 32 33 /** 34 * Initialize a group_req structure with the given interface index and IPv4 35 * multicast group. 36 */ 37 void initGroupReq4(JNIEnv* env, struct group_req *req, jint index, jint group) 38 { 39 struct sockaddr_in* sin; 40 41 #ifdef WIN32 42 req->gr_interface = (ULONG)index; 43 #else 44 req->gr_interface = (uint32_t)index; 45 #endif 46 47 sin = (struct sockaddr_in*)&(req->gr_group); 48 memset(sin, 0, sizeof(struct sockaddr_in)); 49 sin->sin_family = AF_INET; 50 sin->sin_addr.s_addr = htonl(group); 51 } 52 53 /** 54 * Initialize a group_source_req structure with the given interface index, IPv4 55 * multicast group, and IPv4 source address. 56 */ 57 void initGroupSourceReq4(JNIEnv* env, struct group_source_req *req, 58 jint index, jint group, jint source) 59 { 60 struct sockaddr_in* sin; 61 62 #ifdef WIN32 63 req->gsr_interface = (ULONG)index; 64 #else 65 req->gsr_interface = (uint32_t)index; 66 #endif 67 68 sin = (struct sockaddr_in*)&(req->gsr_group); 69 memset(sin, 0, sizeof(struct sockaddr_in)); 70 sin->sin_family = AF_INET; 71 sin->sin_addr.s_addr = htonl(group); 72 73 sin = (struct sockaddr_in*)&(req->gsr_source); 74 memset(sin, 0, sizeof(struct sockaddr_in)); 75 sin->sin_family = AF_INET; 76 sin->sin_addr.s_addr = htonl(source); 77 } 78 79 /** 80 * Initialize a group_req structure with the given interface index and IPv6 81 * multicast group. 82 */ 83 void initGroupReq6(JNIEnv* env, struct group_req *req, jint index, jbyteArray group) 84 { 85 struct sockaddr_in6* sin6; 86 87 #ifdef WIN32 88 req->gr_interface = (ULONG)index; 89 #else 90 req->gr_interface = (uint32_t)index; 91 #endif 92 93 sin6 = (struct sockaddr_in6*)&(req->gr_group); 94 memset(sin6, 0, sizeof(struct sockaddr_in6)); 95 sin6->sin6_family = AF_INET6; 96 COPY_INET6_ADDRESS(env, group, (jbyte*)&(sin6->sin6_addr)); 97 } 98 99 /** 100 * Initialize a group_source req structure with the given interface index, IPv6 101 * multicast group, and IPv6 source address. 102 */ 103 void initGroupSourceReq6(JNIEnv* env, struct group_source_req *req, 104 int index, jbyteArray group, jbyteArray source) 105 { 106 struct sockaddr_in6* sin6; 107 108 #ifdef WIN32 109 req->gsr_interface = (ULONG)index; 110 #else 111 req->gsr_interface = (uint32_t)index; 112 #endif 113 114 sin6 = (struct sockaddr_in6*)&(req->gsr_group); 115 memset(sin6, 0, sizeof(struct sockaddr_in6)); 116 sin6->sin6_family = AF_INET6; 117 COPY_INET6_ADDRESS(env, group, (jbyte*)&(sin6->sin6_addr)); 118 119 sin6 = (struct sockaddr_in6*)&(req->gsr_source); 120 memset(sin6, 0, sizeof(struct sockaddr_in6)); 121 sin6->sin6_family = AF_INET6; 122 COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr)); 123 }