1285 fid = (*env)->GetFieldID(env, cls, "value", "Z");
1286 CHECK_NULL(fid);
1287
1288 on = (*env)->GetBooleanField(env, value, fid);
1289 loopback = (!on ? 1 : 0);
1290
1291 if (NET_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1292 (const void *)&loopback, sizeof(int)) < 0) {
1293 JNU_ThrowByNameWithMessageAndLastError
1294 (env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
1295 return;
1296 }
1297
1298 }
1299 #endif /* AF_INET6 */
1300
1301 /*
1302 * Sets the multicast loopback mode.
1303 */
1304 static void setMulticastLoopbackMode(JNIEnv *env, jobject this, int fd,
1305 jint opt, jobject value) {
1306 #ifdef AF_INET6
1307 #ifdef __linux__
1308 mcast_set_loop_v4(env, this, fd, value);
1309 if (ipv6_available()) {
1310 if ((*env)->ExceptionCheck(env)){
1311 (*env)->ExceptionClear(env);
1312 }
1313 mcast_set_loop_v6(env, this, fd, value);
1314 }
1315 #else /* __linux__ not defined */
1316 if (ipv6_available()) {
1317 mcast_set_loop_v6(env, this, fd, value);
1318 } else {
1319 mcast_set_loop_v4(env, this, fd, value);
1320 }
1321 #endif /* __linux__ */
1322 #else
1323 mcast_set_loop_v4(env, this, fd, value);
1324 #endif /* AF_INET6 */
1325 }
1326
1327 /*
1328 * Class: java_net_PlainDatagramSocketImpl
1329 * Method: socketSetOption0
1330 * Signature: (ILjava/lang/Object;)V
1331 */
1332 JNIEXPORT void JNICALL
1333 Java_java_net_PlainDatagramSocketImpl_socketSetOption0(JNIEnv *env,
1334 jobject this,
1335 jint opt,
1336 jobject value) {
1337 int fd;
1338 int level, optname, optlen;
1339 int optval;
1340 optlen = sizeof(int);
1341
1342 /*
1343 * Check that socket hasn't been closed
1344 */
1345 fd = getFD(env, this);
1346 if (fd < 0) {
1347 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1348 "Socket closed");
1349 return;
1350 }
1351
1352 /*
1353 * Check argument has been provided
1354 */
1355 if (IS_NULL(value)) {
1356 JNU_ThrowNullPointerException(env, "value argument");
1363 if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
1364 opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
1365
1366 setMulticastInterface(env, this, fd, opt, value);
1367 return;
1368 }
1369
1370 /*
1371 * Setting the multicast loopback mode handled separately
1372 */
1373 if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP) {
1374 setMulticastLoopbackMode(env, this, fd, opt, value);
1375 return;
1376 }
1377
1378 /*
1379 * Map the Java level socket option to the platform specific
1380 * level and option name.
1381 */
1382 if (NET_MapSocketOption(opt, &level, &optname)) {
1383 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
1384 return;
1385 }
1386
1387 switch (opt) {
1388 case java_net_SocketOptions_SO_SNDBUF :
1389 case java_net_SocketOptions_SO_RCVBUF :
1390 case java_net_SocketOptions_IP_TOS :
1391 {
1392 jclass cls;
1393 jfieldID fid;
1394
1395 cls = (*env)->FindClass(env, "java/lang/Integer");
1396 CHECK_NULL(cls);
1397 fid = (*env)->GetFieldID(env, cls, "value", "I");
1398 CHECK_NULL(fid);
1399
1400 optval = (*env)->GetIntField(env, value, fid);
1401 break;
1402 }
1403
1682 ni_name = (*env)->NewStringUTF(env, "");
1683 if (ni_name != NULL) {
1684 (*env)->SetObjectField(env, ni, ni_nameID, ni_name);
1685 }
1686 return ni;
1687 }
1688 #endif
1689 return NULL;
1690 }
1691
1692
1693
1694 /*
1695 * Returns relevant info as a jint.
1696 *
1697 * Class: java_net_PlainDatagramSocketImpl
1698 * Method: socketGetOption
1699 * Signature: (I)Ljava/lang/Object;
1700 */
1701 JNIEXPORT jobject JNICALL
1702 Java_java_net_PlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobject this,
1703 jint opt) {
1704 int fd;
1705 int level, optname, optlen;
1706 union {
1707 int i;
1708 char c;
1709 } optval;
1710
1711 fd = getFD(env, this);
1712 if (fd < 0) {
1713 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1714 "socket closed");
1715 return NULL;
1716 }
1717
1718 /*
1719 * Handle IP_MULTICAST_IF separately
1720 */
1721 if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
1722 opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
1723 return getMulticastInterface(env, this, fd, opt);
1734 int port;
1735 jobject iaObj;
1736
1737 len = SOCKADDR_LEN;
1738
1739 if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
1740 JNU_ThrowByNameWithMessageAndLastError
1741 (env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
1742 return NULL;
1743 }
1744 iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
1745
1746 return iaObj;
1747 }
1748
1749 /*
1750 * Map the Java level socket option to the platform specific
1751 * level and option name.
1752 */
1753 if (NET_MapSocketOption(opt, &level, &optname)) {
1754 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
1755 return NULL;
1756 }
1757
1758 if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP &&
1759 level == IPPROTO_IP) {
1760 optlen = sizeof(optval.c);
1761 } else {
1762 optlen = sizeof(optval.i);
1763 }
1764
1765 if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
1766 JNU_ThrowByNameWithMessageAndLastError
1767 (env, JNU_JAVANETPKG "SocketException", "Error getting socket option");
1768 return NULL;
1769 }
1770
1771 switch (opt) {
1772 case java_net_SocketOptions_IP_MULTICAST_LOOP:
1773 /* getLoopbackMode() returns true if IP_MULTICAST_LOOP disabled */
1774 if (level == IPPROTO_IP) {
|
1285 fid = (*env)->GetFieldID(env, cls, "value", "Z");
1286 CHECK_NULL(fid);
1287
1288 on = (*env)->GetBooleanField(env, value, fid);
1289 loopback = (!on ? 1 : 0);
1290
1291 if (NET_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1292 (const void *)&loopback, sizeof(int)) < 0) {
1293 JNU_ThrowByNameWithMessageAndLastError
1294 (env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
1295 return;
1296 }
1297
1298 }
1299 #endif /* AF_INET6 */
1300
1301 /*
1302 * Sets the multicast loopback mode.
1303 */
1304 static void setMulticastLoopbackMode(JNIEnv *env, jobject this, int fd,
1305 jint opt, jobject value) {
1306 #ifdef AF_INET6
1307 #ifdef __linux__
1308 mcast_set_loop_v4(env, this, fd, value);
1309 if (ipv6_available()) {
1310 if ((*env)->ExceptionCheck(env)){
1311 (*env)->ExceptionClear(env);
1312 }
1313 mcast_set_loop_v6(env, this, fd, value);
1314 }
1315 #else /* __linux__ not defined */
1316 if (ipv6_available()) {
1317 mcast_set_loop_v6(env, this, fd, value);
1318 } else {
1319 mcast_set_loop_v4(env, this, fd, value);
1320 }
1321 #endif /* __linux__ */
1322 #else
1323 mcast_set_loop_v4(env, this, fd, value);
1324 #endif /* AF_INET6 */
1325 }
1326
1327 /*
1328 * Class: java_net_PlainDatagramSocketImpl
1329 * Method: socketSetOption0
1330 * Signature: (ILjava/lang/Object;)V
1331 */
1332 JNIEXPORT void JNICALL
1333 Java_java_net_PlainDatagramSocketImpl_socketSetOption0
1334 (JNIEnv *env, jobject this, jint opt, jobject value)
1335 {
1336 int fd;
1337 int level, optname, optlen;
1338 int optval;
1339 optlen = sizeof(int);
1340
1341 /*
1342 * Check that socket hasn't been closed
1343 */
1344 fd = getFD(env, this);
1345 if (fd < 0) {
1346 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1347 "Socket closed");
1348 return;
1349 }
1350
1351 /*
1352 * Check argument has been provided
1353 */
1354 if (IS_NULL(value)) {
1355 JNU_ThrowNullPointerException(env, "value argument");
1362 if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
1363 opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
1364
1365 setMulticastInterface(env, this, fd, opt, value);
1366 return;
1367 }
1368
1369 /*
1370 * Setting the multicast loopback mode handled separately
1371 */
1372 if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP) {
1373 setMulticastLoopbackMode(env, this, fd, opt, value);
1374 return;
1375 }
1376
1377 /*
1378 * Map the Java level socket option to the platform specific
1379 * level and option name.
1380 */
1381 if (NET_MapSocketOption(opt, &level, &optname)) {
1382 JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
1383 return;
1384 }
1385
1386 switch (opt) {
1387 case java_net_SocketOptions_SO_SNDBUF :
1388 case java_net_SocketOptions_SO_RCVBUF :
1389 case java_net_SocketOptions_IP_TOS :
1390 {
1391 jclass cls;
1392 jfieldID fid;
1393
1394 cls = (*env)->FindClass(env, "java/lang/Integer");
1395 CHECK_NULL(cls);
1396 fid = (*env)->GetFieldID(env, cls, "value", "I");
1397 CHECK_NULL(fid);
1398
1399 optval = (*env)->GetIntField(env, value, fid);
1400 break;
1401 }
1402
1681 ni_name = (*env)->NewStringUTF(env, "");
1682 if (ni_name != NULL) {
1683 (*env)->SetObjectField(env, ni, ni_nameID, ni_name);
1684 }
1685 return ni;
1686 }
1687 #endif
1688 return NULL;
1689 }
1690
1691
1692
1693 /*
1694 * Returns relevant info as a jint.
1695 *
1696 * Class: java_net_PlainDatagramSocketImpl
1697 * Method: socketGetOption
1698 * Signature: (I)Ljava/lang/Object;
1699 */
1700 JNIEXPORT jobject JNICALL
1701 Java_java_net_PlainDatagramSocketImpl_socketGetOption
1702 (JNIEnv *env, jobject this, jint opt)
1703 {
1704 int fd;
1705 int level, optname, optlen;
1706 union {
1707 int i;
1708 char c;
1709 } optval;
1710
1711 fd = getFD(env, this);
1712 if (fd < 0) {
1713 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1714 "socket closed");
1715 return NULL;
1716 }
1717
1718 /*
1719 * Handle IP_MULTICAST_IF separately
1720 */
1721 if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
1722 opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
1723 return getMulticastInterface(env, this, fd, opt);
1734 int port;
1735 jobject iaObj;
1736
1737 len = SOCKADDR_LEN;
1738
1739 if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
1740 JNU_ThrowByNameWithMessageAndLastError
1741 (env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
1742 return NULL;
1743 }
1744 iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
1745
1746 return iaObj;
1747 }
1748
1749 /*
1750 * Map the Java level socket option to the platform specific
1751 * level and option name.
1752 */
1753 if (NET_MapSocketOption(opt, &level, &optname)) {
1754 JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
1755 return NULL;
1756 }
1757
1758 if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP &&
1759 level == IPPROTO_IP) {
1760 optlen = sizeof(optval.c);
1761 } else {
1762 optlen = sizeof(optval.i);
1763 }
1764
1765 if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
1766 JNU_ThrowByNameWithMessageAndLastError
1767 (env, JNU_JAVANETPKG "SocketException", "Error getting socket option");
1768 return NULL;
1769 }
1770
1771 switch (opt) {
1772 case java_net_SocketOptions_IP_MULTICAST_LOOP:
1773 /* getLoopbackMode() returns true if IP_MULTICAST_LOOP disabled */
1774 if (level == IPPROTO_IP) {
|