1 /* |
1 /* |
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
49 #ifndef IP_MULTICAST_ALL |
52 #ifndef IP_MULTICAST_ALL |
50 #define IP_MULTICAST_ALL 49 |
53 #define IP_MULTICAST_ALL 49 |
51 #endif |
54 #endif |
52 #endif |
55 #endif |
53 |
56 |
54 #ifdef _ALLBSD_SOURCE |
57 #if defined(_ALLBSD_SOURCE) || defined(_AIX) |
55 |
58 |
56 #ifndef IP_BLOCK_SOURCE |
59 #ifndef IP_BLOCK_SOURCE |
|
60 |
|
61 #if defined(_AIX) |
|
62 |
|
63 #define IP_BLOCK_SOURCE 58 /* Block data from a given source to a given group */ |
|
64 #define IP_UNBLOCK_SOURCE 59 /* Unblock data from a given source to a given group */ |
|
65 #define IP_ADD_SOURCE_MEMBERSHIP 60 /* Join a source-specific group */ |
|
66 #define IP_DROP_SOURCE_MEMBERSHIP 61 /* Leave a source-specific group */ |
|
67 |
|
68 #else |
57 |
69 |
58 #define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */ |
70 #define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */ |
59 #define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */ |
71 #define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */ |
60 #define IP_BLOCK_SOURCE 72 /* block a source */ |
72 #define IP_BLOCK_SOURCE 72 /* block a source */ |
61 #define IP_UNBLOCK_SOURCE 73 /* unblock a source */ |
73 #define IP_UNBLOCK_SOURCE 73 /* unblock a source */ |
62 |
74 |
|
75 #endif /* _AIX */ |
|
76 |
63 #endif /* IP_BLOCK_SOURCE */ |
77 #endif /* IP_BLOCK_SOURCE */ |
64 |
78 |
65 #ifndef MCAST_BLOCK_SOURCE |
79 #ifndef MCAST_BLOCK_SOURCE |
|
80 |
|
81 #if defined(_AIX) |
|
82 |
|
83 #define MCAST_BLOCK_SOURCE 64 |
|
84 #define MCAST_UNBLOCK_SOURCE 65 |
|
85 #define MCAST_JOIN_SOURCE_GROUP 66 |
|
86 #define MCAST_LEAVE_SOURCE_GROUP 67 |
|
87 |
|
88 #else |
66 |
89 |
67 #define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */ |
90 #define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */ |
68 #define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */ |
91 #define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */ |
69 #define MCAST_BLOCK_SOURCE 84 /* block a source */ |
92 #define MCAST_BLOCK_SOURCE 84 /* block a source */ |
70 #define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */ |
93 #define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */ |
|
94 |
|
95 #endif /* _AIX */ |
71 |
96 |
72 #endif /* MCAST_BLOCK_SOURCE */ |
97 #endif /* MCAST_BLOCK_SOURCE */ |
73 |
98 |
74 #ifndef IPV6_ADD_MEMBERSHIP |
99 #ifndef IPV6_ADD_MEMBERSHIP |
75 |
100 |
120 sin6 = (struct sockaddr_in6*)&(req->gsr_source); |
145 sin6 = (struct sockaddr_in6*)&(req->gsr_source); |
121 sin6->sin6_family = AF_INET6; |
146 sin6->sin6_family = AF_INET6; |
122 COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr)); |
147 COPY_INET6_ADDRESS(env, source, (jbyte*)&(sin6->sin6_addr)); |
123 } |
148 } |
124 #endif |
149 #endif |
|
150 |
|
151 #ifdef _AIX |
|
152 |
|
153 /* |
|
154 * Checks whether or not "socket extensions for multicast source filters" is supported. |
|
155 * Returns JNI_TRUE if it is supported, JNI_FALSE otherwise |
|
156 */ |
|
157 static jboolean isSourceFilterSupported(){ |
|
158 static jboolean alreadyChecked = JNI_FALSE; |
|
159 static jboolean result = JNI_TRUE; |
|
160 if (alreadyChecked != JNI_TRUE){ |
|
161 struct utsname uts; |
|
162 memset(&uts, 0, sizeof(uts)); |
|
163 strcpy(uts.sysname, "?"); |
|
164 const int utsRes = uname(&uts); |
|
165 int major = -1; |
|
166 int minor = -1; |
|
167 major = atoi(uts.version); |
|
168 minor = atoi(uts.release); |
|
169 if (strcmp(uts.sysname, "AIX") == 0) { |
|
170 if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1 |
|
171 result = JNI_FALSE; |
|
172 } |
|
173 } |
|
174 alreadyChecked = JNI_TRUE; |
|
175 } |
|
176 return result; |
|
177 } |
|
178 |
|
179 #endif /* _AIX */ |
125 |
180 |
126 JNIEXPORT void JNICALL |
181 JNIEXPORT void JNICALL |
127 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz) |
182 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz) |
128 { |
183 { |
129 /* Here because Windows native code does need to init IDs */ |
184 /* Here because Windows native code does need to init IDs */ |
473 } else { |
528 } else { |
474 #ifdef MACOSX |
529 #ifdef MACOSX |
475 /* no IPv4 include-mode filtering for now */ |
530 /* no IPv4 include-mode filtering for now */ |
476 return IOS_UNAVAILABLE; |
531 return IOS_UNAVAILABLE; |
477 #else |
532 #else |
|
533 |
|
534 #ifdef _AIX |
|
535 /* check AIX for support of source filtering */ |
|
536 if (isSourceFilterSupported() != JNI_TRUE){ |
|
537 return IOS_UNAVAILABLE; |
|
538 } |
|
539 #endif |
|
540 |
478 mreq_source.imr_multiaddr.s_addr = htonl(group); |
541 mreq_source.imr_multiaddr.s_addr = htonl(group); |
479 mreq_source.imr_sourceaddr.s_addr = htonl(source); |
542 mreq_source.imr_sourceaddr.s_addr = htonl(source); |
480 mreq_source.imr_interface.s_addr = htonl(interf); |
543 mreq_source.imr_interface.s_addr = htonl(interf); |
481 opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP; |
544 opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP; |
482 optval = (void*)&mreq_source; |
545 optval = (void*)&mreq_source; |
484 #endif |
547 #endif |
485 } |
548 } |
486 |
549 |
487 n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen); |
550 n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen); |
488 if (n < 0) { |
551 if (n < 0) { |
489 if (join && (errno == ENOPROTOOPT)) |
552 if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) |
490 return IOS_UNAVAILABLE; |
553 return IOS_UNAVAILABLE; |
491 handleSocketError(env, errno); |
554 handleSocketError(env, errno); |
492 } |
555 } |
493 return 0; |
556 return 0; |
494 } |
557 } |
503 #else |
566 #else |
504 struct my_ip_mreq_source mreq_source; |
567 struct my_ip_mreq_source mreq_source; |
505 int n; |
568 int n; |
506 int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE; |
569 int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE; |
507 |
570 |
|
571 #ifdef _AIX |
|
572 /* check AIX for support of source filtering */ |
|
573 if (isSourceFilterSupported() != JNI_TRUE){ |
|
574 return IOS_UNAVAILABLE; |
|
575 } |
|
576 #endif |
|
577 |
508 mreq_source.imr_multiaddr.s_addr = htonl(group); |
578 mreq_source.imr_multiaddr.s_addr = htonl(group); |
509 mreq_source.imr_sourceaddr.s_addr = htonl(source); |
579 mreq_source.imr_sourceaddr.s_addr = htonl(source); |
510 mreq_source.imr_interface.s_addr = htonl(interf); |
580 mreq_source.imr_interface.s_addr = htonl(interf); |
511 |
581 |
512 n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, |
582 n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, |
513 (void*)&mreq_source, sizeof(mreq_source)); |
583 (void*)&mreq_source, sizeof(mreq_source)); |
514 if (n < 0) { |
584 if (n < 0) { |
515 if (block && (errno == ENOPROTOOPT)) |
585 if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) |
516 return IOS_UNAVAILABLE; |
586 return IOS_UNAVAILABLE; |
517 handleSocketError(env, errno); |
587 handleSocketError(env, errno); |
518 } |
588 } |
519 return 0; |
589 return 0; |
520 #endif |
590 #endif |
548 #endif |
618 #endif |
549 } |
619 } |
550 |
620 |
551 n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen); |
621 n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen); |
552 if (n < 0) { |
622 if (n < 0) { |
553 if (join && (errno == ENOPROTOOPT)) |
623 if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) |
554 return IOS_UNAVAILABLE; |
624 return IOS_UNAVAILABLE; |
555 handleSocketError(env, errno); |
625 handleSocketError(env, errno); |
556 } |
626 } |
557 return 0; |
627 return 0; |
558 #else |
628 #else |
577 initGroupSourceReq(env, group, index, source, &req); |
647 initGroupSourceReq(env, group, index, source, &req); |
578 |
648 |
579 n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, |
649 n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, |
580 (void*)&req, sizeof(req)); |
650 (void*)&req, sizeof(req)); |
581 if (n < 0) { |
651 if (n < 0) { |
582 if (block && (errno == ENOPROTOOPT)) |
652 if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) |
583 return IOS_UNAVAILABLE; |
653 return IOS_UNAVAILABLE; |
584 handleSocketError(env, errno); |
654 handleSocketError(env, errno); |
585 } |
655 } |
586 return 0; |
656 return 0; |
587 #endif |
657 #endif |