src/solaris/native/sun/nio/ch/Net.c

Print this page




  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 */