22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/socket.h> 28 #include <string.h> 29 #include <netinet/in.h> 30 #include <netinet/tcp.h> 31 32 #include "jni.h" 33 #include "jni_util.h" 34 #include "jvm.h" 35 #include "jlong.h" 36 #include "sun_nio_ch_Net.h" 37 #include "net_util.h" 38 #include "net_util_md.h" 39 #include "nio_util.h" 40 #include "nio.h" 41 42 /** 43 * Definitions for source-specific multicast to allow for building 44 * with older header files. 45 */ 46 47 #ifdef __solaris__ 48 49 #ifndef IP_BLOCK_SOURCE 50 51 #define IP_BLOCK_SOURCE 0x15 52 #define IP_UNBLOCK_SOURCE 0x16 53 #define IP_ADD_SOURCE_MEMBERSHIP 0x17 54 #define IP_DROP_SOURCE_MEMBERSHIP 0x18 55 56 #define MCAST_BLOCK_SOURCE 0x2b 57 #define MCAST_UNBLOCK_SOURCE 0x2c 58 #define MCAST_JOIN_SOURCE_GROUP 0x2d 59 #define MCAST_LEAVE_SOURCE_GROUP 0x2e 60 61 #endif /* IP_BLOCK_SOURCE */ 62 63 struct my_ip_mreq_source { 64 struct in_addr imr_multiaddr; 65 struct in_addr imr_sourceaddr; 66 struct in_addr imr_interface; 67 }; 68 69 /* 70 * Use #pragma pack() construct to force 32-bit alignment on amd64. 71 */ 72 #if defined(amd64) 73 #pragma pack(4) 74 #endif 75 76 struct my_group_source_req { 77 uint32_t gsr_interface; /* interface index */ 78 struct sockaddr_storage gsr_group; /* group address */ 79 struct sockaddr_storage gsr_source; /* source address */ 80 }; 81 82 #if defined(amd64) 83 #pragma pack() 84 #endif 85 86 #endif /* __solaris__ */ 87 88 89 #ifdef __linux__ 90 91 #ifndef IP_BLOCK_SOURCE 92 93 #define IP_BLOCK_SOURCE 38 94 #define IP_UNBLOCK_SOURCE 37 95 #define IP_ADD_SOURCE_MEMBERSHIP 39 96 #define IP_DROP_SOURCE_MEMBERSHIP 40 97 98 #define MCAST_BLOCK_SOURCE 43 99 #define MCAST_UNBLOCK_SOURCE 44 100 #define MCAST_JOIN_SOURCE_GROUP 42 101 #define MCAST_LEAVE_SOURCE_GROUP 45 102 103 #endif /* IP_BLOCK_SOURCE */ 104 105 struct my_ip_mreq_source { 106 struct in_addr imr_multiaddr; 107 struct in_addr imr_interface; 108 struct in_addr imr_sourceaddr; 109 }; 110 111 struct my_group_source_req { 112 uint32_t gsr_interface; /* interface index */ 113 struct sockaddr_storage gsr_group; /* group address */ 114 struct sockaddr_storage gsr_source; /* source address */ 115 }; 116 117 #endif /* __linux__ */ 118 119 #ifdef _ALLBSD_SOURCE 120 121 #ifndef IP_BLOCK_SOURCE 122 123 #define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */ 124 #define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */ 125 #define IP_BLOCK_SOURCE 72 /* block a source */ 126 #define IP_UNBLOCK_SOURCE 73 /* unblock a source */ 127 128 #endif /* IP_BLOCK_SOURCE */ 129 130 #ifndef MCAST_BLOCK_SOURCE 131 132 #define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */ 133 #define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */ 134 #define MCAST_BLOCK_SOURCE 84 /* block a source */ 135 #define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */ 136 137 #endif /* MCAST_BLOCK_SOURCE */ 138 139 #ifndef IPV6_ADD_MEMBERSHIP 140 141 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 142 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP 143 144 #endif /* IPV6_ADD_MEMBERSHIP */ 145 146 struct my_ip_mreq_source { 147 struct in_addr imr_multiaddr; 148 struct in_addr imr_interface; 149 struct in_addr imr_sourceaddr; 150 }; 151 152 struct my_group_source_req { 153 uint32_t gsr_interface; /* interface index */ 154 struct sockaddr_storage gsr_group; /* group address */ 155 struct sockaddr_storage gsr_source; /* source address */ 156 }; 157 158 #endif /* _ALLBSD_SOURCE */ 159 160 161 #define COPY_INET6_ADDRESS(env, source, target) \ 162 (*env)->GetByteArrayRegion(env, source, 0, 16, target) 163 164 /* 165 * Copy IPv6 group, interface index, and IPv6 source address 166 * into group_source_req structure. 167 */ 168 #ifdef AF_INET6 169 static void initGroupSourceReq(JNIEnv* env, jbyteArray group, jint index, 170 jbyteArray source, struct my_group_source_req* req) 171 { 172 struct sockaddr_in6* sin6; 173 174 req->gsr_interface = (uint32_t)index; 175 176 sin6 = (struct sockaddr_in6*)&(req->gsr_group); 177 sin6->sin6_family = AF_INET6; 178 COPY_INET6_ADDRESS(env, group, (jbyte*)&(sin6->sin6_addr)); 179 180 sin6 = (struct sockaddr_in6*)&(req->gsr_source); 559 #endif 560 } 561 562 JNIEXPORT jint JNICALL 563 Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobject fdo, 564 jbyteArray group, jint index, jbyteArray source) 565 { 566 #ifdef AF_INET6 567 struct ipv6_mreq mreq6; 568 struct my_group_source_req req; 569 int opt, n, optlen; 570 void* optval; 571 572 if (source == NULL) { 573 COPY_INET6_ADDRESS(env, group, (jbyte*)&(mreq6.ipv6mr_multiaddr)); 574 mreq6.ipv6mr_interface = (int)index; 575 opt = (join) ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP; 576 optval = (void*)&mreq6; 577 optlen = sizeof(mreq6); 578 } else { 579 #if defined (__linux__) || defined(MACOSX) 580 /* Include-mode filtering broken on Mac OS & Linux at least to 2.6.24 */ 581 return IOS_UNAVAILABLE; 582 #else 583 initGroupSourceReq(env, group, index, source, &req); 584 opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP; 585 optval = (void*)&req; 586 optlen = sizeof(req); 587 #endif 588 } 589 590 n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen); 591 if (n < 0) { 592 if (join && (errno == ENOPROTOOPT)) 593 return IOS_UNAVAILABLE; 594 handleSocketError(env, errno); 595 } 596 return 0; 597 #else 598 JNU_ThrowInternalError(env, "Should not get here"); 599 return IOS_THROWN; 600 #endif /* AF_INET6 */ | 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/socket.h> 28 #include <string.h> 29 #include <netinet/in.h> 30 #include <netinet/tcp.h> 31 32 #include "jni.h" 33 #include "jni_util.h" 34 #include "jvm.h" 35 #include "jlong.h" 36 #include "sun_nio_ch_Net.h" 37 #include "net_util.h" 38 #include "net_util_md.h" 39 #include "nio_util.h" 40 #include "nio.h" 41 42 #ifdef _ALLBSD_SOURCE 43 44 #ifndef IP_BLOCK_SOURCE 45 46 #define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */ 47 #define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */ 48 #define IP_BLOCK_SOURCE 72 /* block a source */ 49 #define IP_UNBLOCK_SOURCE 73 /* unblock a source */ 50 51 #endif /* IP_BLOCK_SOURCE */ 52 53 #ifndef MCAST_BLOCK_SOURCE 54 55 #define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */ 56 #define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */ 57 #define MCAST_BLOCK_SOURCE 84 /* block a source */ 58 #define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */ 59 60 #endif /* MCAST_BLOCK_SOURCE */ 61 62 #ifndef IPV6_ADD_MEMBERSHIP 63 64 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 65 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP 66 67 #endif /* IPV6_ADD_MEMBERSHIP */ 68 69 struct my_ip_mreq_source { 70 struct in_addr imr_multiaddr; 71 struct in_addr imr_interface; 72 struct in_addr imr_sourceaddr; 73 }; 74 75 struct my_group_source_req { 76 uint32_t gsr_interface; /* interface index */ 77 struct sockaddr_storage gsr_group; /* group address */ 78 struct sockaddr_storage gsr_source; /* source address */ 79 }; 80 81 #else /* _ALLBSD_SOURCE */ 82 83 #define my_ip_mreq_source ip_mreq_source 84 #define my_group_source_req group_source_req 85 86 #endif 87 88 89 #define COPY_INET6_ADDRESS(env, source, target) \ 90 (*env)->GetByteArrayRegion(env, source, 0, 16, target) 91 92 /* 93 * Copy IPv6 group, interface index, and IPv6 source address 94 * into group_source_req structure. 95 */ 96 #ifdef AF_INET6 97 static void initGroupSourceReq(JNIEnv* env, jbyteArray group, jint index, 98 jbyteArray source, struct my_group_source_req* req) 99 { 100 struct sockaddr_in6* sin6; 101 102 req->gsr_interface = (uint32_t)index; 103 104 sin6 = (struct sockaddr_in6*)&(req->gsr_group); 105 sin6->sin6_family = AF_INET6; 106 COPY_INET6_ADDRESS(env, group, (jbyte*)&(sin6->sin6_addr)); 107 108 sin6 = (struct sockaddr_in6*)&(req->gsr_source); 487 #endif 488 } 489 490 JNIEXPORT jint JNICALL 491 Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobject fdo, 492 jbyteArray group, jint index, jbyteArray source) 493 { 494 #ifdef AF_INET6 495 struct ipv6_mreq mreq6; 496 struct my_group_source_req req; 497 int opt, n, optlen; 498 void* optval; 499 500 if (source == NULL) { 501 COPY_INET6_ADDRESS(env, group, (jbyte*)&(mreq6.ipv6mr_multiaddr)); 502 mreq6.ipv6mr_interface = (int)index; 503 opt = (join) ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP; 504 optval = (void*)&mreq6; 505 optlen = sizeof(mreq6); 506 } else { 507 #ifdef MACOSX 508 /* no IPv6 include-mode filtering for now */ 509 return IOS_UNAVAILABLE; 510 #else 511 initGroupSourceReq(env, group, index, source, &req); 512 opt = (join) ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP; 513 optval = (void*)&req; 514 optlen = sizeof(req); 515 #endif 516 } 517 518 n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen); 519 if (n < 0) { 520 if (join && (errno == ENOPROTOOPT)) 521 return IOS_UNAVAILABLE; 522 handleSocketError(env, errno); 523 } 524 return 0; 525 #else 526 JNU_ThrowInternalError(env, "Should not get here"); 527 return IOS_THROWN; 528 #endif /* AF_INET6 */ |