430 |
430 |
431 SOCKETADDRESS lcladdr; |
431 SOCKETADDRESS lcladdr; |
432 int lcladdrlen; |
432 int lcladdrlen; |
433 int address; |
433 int address; |
434 |
434 |
435 family = (*env)->GetIntField(env, addressObj, ia_familyID); |
435 family = getInetAddress_family(env, addressObj); |
436 if (family == IPv6 && !ipv6_supported) { |
436 if (family == IPv6 && !ipv6_supported) { |
437 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", |
437 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", |
438 "Protocol family not supported"); |
438 "Protocol family not supported"); |
439 return; |
439 return; |
440 } |
440 } |
450 } |
450 } |
451 if (IS_NULL(addressObj)) { |
451 if (IS_NULL(addressObj)) { |
452 JNU_ThrowNullPointerException(env, "argument address"); |
452 JNU_ThrowNullPointerException(env, "argument address"); |
453 return; |
453 return; |
454 } else { |
454 } else { |
455 address = (*env)->GetIntField(env, addressObj, ia_addressID); |
455 address = getInetAddress_addr(env, addressObj); |
456 } |
456 } |
457 |
457 |
458 if (NET_InetAddressToSockaddr(env, addressObj, port, (struct sockaddr *)&lcladdr, &lcladdrlen, JNI_FALSE) != 0) { |
458 if (NET_InetAddressToSockaddr(env, addressObj, port, (struct sockaddr *)&lcladdr, &lcladdrlen, JNI_FALSE) != 0) { |
459 return; |
459 return; |
460 } |
460 } |
550 if (IS_NULL(address)) { |
550 if (IS_NULL(address)) { |
551 JNU_ThrowNullPointerException(env, "address"); |
551 JNU_ThrowNullPointerException(env, "address"); |
552 return; |
552 return; |
553 } |
553 } |
554 |
554 |
555 addr = (*env)->GetIntField(env, address, ia_addressID); |
555 addr = getInetAddress_addr(env, address); |
556 |
556 |
557 family = (*env)->GetIntField(env, address, ia_familyID); |
557 family = getInetAddress_family(env, address); |
558 if (family == IPv6 && !ipv6_supported) { |
558 if (family == IPv6 && !ipv6_supported) { |
559 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", |
559 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", |
560 "Protocol family not supported"); |
560 "Protocol family not supported"); |
561 return; |
561 return; |
562 } |
562 } |
668 if (IS_NULL(iaObj) || IS_NULL(packetBuffer)) { |
668 if (IS_NULL(iaObj) || IS_NULL(packetBuffer)) { |
669 JNU_ThrowNullPointerException(env, "null address || null buffer"); |
669 JNU_ThrowNullPointerException(env, "null address || null buffer"); |
670 return; |
670 return; |
671 } |
671 } |
672 |
672 |
673 family = (*env)->GetIntField(env, iaObj, ia_familyID); |
673 family = getInetAddress_family(env, iaObj); |
674 if (family == IPv4) { |
674 if (family == IPv4) { |
675 fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); |
675 fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); |
676 } else { |
676 } else { |
677 if (!ipv6_available()) { |
677 if (!ipv6_available()) { |
678 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", |
678 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", |
712 * returned. |
712 * returned. |
713 */ |
713 */ |
714 if (!w2k_or_later) { /* avoid this check on Win 2K or better. Does not work with IPv6. |
714 if (!w2k_or_later) { /* avoid this check on Win 2K or better. Does not work with IPv6. |
715 * Check is not necessary on these OSes */ |
715 * Check is not necessary on these OSes */ |
716 if (connected) { |
716 if (connected) { |
717 address = (*env)->GetIntField(env, iaObj, ia_addressID); |
717 address = getInetAddress_addr(env, iaObj); |
718 } else { |
718 } else { |
719 address = ntohl(rmtaddr.him4.sin_addr.s_addr); |
719 address = ntohl(rmtaddr.him4.sin_addr.s_addr); |
720 } |
720 } |
721 |
721 |
722 if (exceedSizeLimit(env, fd, address, packetBufferLen)) { |
722 if (exceedSizeLimit(env, fd, address, packetBufferLen)) { |
821 } |
821 } |
822 } |
822 } |
823 if (IS_NULL(addressObj)) { |
823 if (IS_NULL(addressObj)) { |
824 JNU_ThrowNullPointerException(env, "Null address in peek()"); |
824 JNU_ThrowNullPointerException(env, "Null address in peek()"); |
825 } else { |
825 } else { |
826 address = (*env)->GetIntField(env, addressObj, ia_addressID); |
826 address = getInetAddress_addr(env, addressObj); |
827 /* We only handle IPv4 for now. Will support IPv6 once its in the os */ |
827 /* We only handle IPv4 for now. Will support IPv6 once its in the os */ |
828 family = AF_INET; |
828 family = AF_INET; |
829 } |
829 } |
830 |
830 |
831 do { |
831 do { |
903 } |
903 } |
904 if (n == JVM_IO_INTR) { |
904 if (n == JVM_IO_INTR) { |
905 JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", 0); |
905 JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", 0); |
906 return 0; |
906 return 0; |
907 } |
907 } |
908 (*env)->SetIntField(env, addressObj, ia_addressID, |
908 setInetAddress_addr(env, addressObj, ntohl(remote_addr.sin_addr.s_addr)); |
909 ntohl(remote_addr.sin_addr.s_addr)); |
909 setInetAddress_family(env, addressObj, IPv4); |
910 (*env)->SetIntField(env, addressObj, ia_familyID, IPv4); |
|
911 |
910 |
912 /* return port */ |
911 /* return port */ |
913 return ntohs(remote_addr.sin_port); |
912 return ntohs(remote_addr.sin_port); |
914 } |
913 } |
915 |
914 |
1572 |
1571 |
1573 static int getInetAddrFromIf (JNIEnv *env, int family, jobject nif, jobject *iaddr) |
1572 static int getInetAddrFromIf (JNIEnv *env, int family, jobject nif, jobject *iaddr) |
1574 { |
1573 { |
1575 jobjectArray addrArray; |
1574 jobjectArray addrArray; |
1576 static jfieldID ni_addrsID=0; |
1575 static jfieldID ni_addrsID=0; |
1577 static jfieldID ia_familyID=0; |
|
1578 jsize len; |
1576 jsize len; |
1579 jobject addr; |
1577 jobject addr; |
1580 int i; |
1578 int i; |
1581 |
1579 |
1582 if (ni_addrsID == NULL || ia_familyID == NULL) { |
1580 if (ni_addrsID == NULL ) { |
1583 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); |
1581 jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); |
1584 CHECK_NULL_RETURN (c, -1); |
1582 CHECK_NULL_RETURN (c, -1); |
1585 ni_addrsID = (*env)->GetFieldID(env, c, "addrs", |
1583 ni_addrsID = (*env)->GetFieldID(env, c, "addrs", |
1586 "[Ljava/net/InetAddress;"); |
1584 "[Ljava/net/InetAddress;"); |
1587 CHECK_NULL_RETURN (ni_addrsID, -1); |
1585 CHECK_NULL_RETURN (ni_addrsID, -1); |
1588 c = (*env)->FindClass(env,"java/net/InetAddress"); |
|
1589 CHECK_NULL_RETURN (c, -1); |
|
1590 ia_familyID = (*env)->GetFieldID(env, c, "family", "I"); |
|
1591 CHECK_NULL_RETURN (ia_familyID, -1); |
|
1592 } |
1586 } |
1593 |
1587 |
1594 addrArray = (*env)->GetObjectField(env, nif, ni_addrsID); |
1588 addrArray = (*env)->GetObjectField(env, nif, ni_addrsID); |
1595 len = (*env)->GetArrayLength(env, addrArray); |
1589 len = (*env)->GetArrayLength(env, addrArray); |
1596 |
1590 |
1604 return -1; |
1598 return -1; |
1605 } |
1599 } |
1606 for (i=0; i<len; i++) { |
1600 for (i=0; i<len; i++) { |
1607 int fam; |
1601 int fam; |
1608 addr = (*env)->GetObjectArrayElement(env, addrArray, i); |
1602 addr = (*env)->GetObjectArrayElement(env, addrArray, i); |
1609 fam = (*env)->GetIntField(env, addr, ia_familyID); |
1603 fam = getInetAddress_family(env, addr); |
1610 if (fam == family) { |
1604 if (fam == family) { |
1611 *iaddr = addr; |
1605 *iaddr = addr; |
1612 return 0; |
1606 return 0; |
1613 } |
1607 } |
1614 } |
1608 } |
1616 } |
1610 } |
1617 |
1611 |
1618 static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr) |
1612 static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr) |
1619 { |
1613 { |
1620 jobject addr; |
1614 jobject addr; |
1621 static jfieldID ia_addressID; |
|
1622 |
1615 |
1623 int ret = getInetAddrFromIf (env, IPv4, nif, &addr); |
1616 int ret = getInetAddrFromIf (env, IPv4, nif, &addr); |
1624 if (ret == -1) { |
1617 if (ret == -1) { |
1625 return -1; |
1618 return -1; |
1626 } |
1619 } |
1627 |
1620 |
1628 if (ia_addressID == 0) { |
1621 iaddr->s_addr = htonl(getInetAddress_addr(env, addr)); |
1629 jclass c = (*env)->FindClass(env,"java/net/InetAddress"); |
|
1630 CHECK_NULL_RETURN (c, -1); |
|
1631 ia_addressID = (*env)->GetFieldID(env, c, "address", "I"); |
|
1632 CHECK_NULL_RETURN (ia_addressID, -1); |
|
1633 } |
|
1634 iaddr->s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID)); |
|
1635 return 0; |
1622 return 0; |
1636 } |
1623 } |
1637 |
1624 |
1638 /* Get the multicasting index from the interface */ |
1625 /* Get the multicasting index from the interface */ |
1639 |
1626 |
1704 } |
1691 } |
1705 return; |
1692 return; |
1706 } |
1693 } |
1707 opt = java_net_SocketOptions_IP_MULTICAST_IF2; |
1694 opt = java_net_SocketOptions_IP_MULTICAST_IF2; |
1708 } else { |
1695 } else { |
1709 static jfieldID ia_addressID; |
|
1710 struct in_addr in; |
1696 struct in_addr in; |
1711 |
1697 |
1712 if (ia_addressID == NULL) { |
1698 in.s_addr = htonl(getInetAddress_addr(env, value)); |
1713 jclass c = (*env)->FindClass(env,"java/net/InetAddress"); |
|
1714 CHECK_NULL(c); |
|
1715 ia_addressID = (*env)->GetFieldID(env, c, "address", "I"); |
|
1716 CHECK_NULL(ia_addressID); |
|
1717 } |
|
1718 |
|
1719 in.s_addr = htonl((*env)->GetIntField(env, value, ia_addressID)); |
|
1720 |
1699 |
1721 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, |
1700 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, |
1722 (const char*)&in, sizeof(in)) < 0) { |
1701 (const char*)&in, sizeof(in)) < 0) { |
1723 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", |
1702 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", |
1724 "Error setting socket option"); |
1703 "Error setting socket option"); |
1943 * IPv4 implementation |
1922 * IPv4 implementation |
1944 */ |
1923 */ |
1945 if (isIPV4) { |
1924 if (isIPV4) { |
1946 static jclass inet4_class; |
1925 static jclass inet4_class; |
1947 static jmethodID inet4_ctrID; |
1926 static jmethodID inet4_ctrID; |
1948 static jfieldID inet4_addrID; |
|
1949 |
1927 |
1950 static jclass ni_class; |
1928 static jclass ni_class; |
1951 static jmethodID ni_ctrID; |
1929 static jmethodID ni_ctrID; |
1952 static jfieldID ni_indexID; |
1930 static jfieldID ni_indexID; |
1953 static jfieldID ni_addrsID; |
1931 static jfieldID ni_addrsID; |
1973 if (inet4_class == NULL) { |
1951 if (inet4_class == NULL) { |
1974 jclass c = (*env)->FindClass(env, "java/net/Inet4Address"); |
1952 jclass c = (*env)->FindClass(env, "java/net/Inet4Address"); |
1975 CHECK_NULL_RETURN(c, NULL); |
1953 CHECK_NULL_RETURN(c, NULL); |
1976 inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V"); |
1954 inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V"); |
1977 CHECK_NULL_RETURN(inet4_ctrID, NULL); |
1955 CHECK_NULL_RETURN(inet4_ctrID, NULL); |
1978 inet4_addrID = (*env)->GetFieldID(env, c, "address", "I"); |
|
1979 CHECK_NULL_RETURN(inet4_addrID, NULL); |
|
1980 inet4_class = (*env)->NewGlobalRef(env, c); |
1956 inet4_class = (*env)->NewGlobalRef(env, c); |
1981 CHECK_NULL_RETURN(inet4_class, NULL); |
1957 CHECK_NULL_RETURN(inet4_class, NULL); |
1982 } |
1958 } |
1983 addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0); |
1959 addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0); |
1984 CHECK_NULL_RETURN(addr, NULL); |
1960 CHECK_NULL_RETURN(addr, NULL); |
1985 |
1961 |
1986 (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr)); |
1962 setInetAddress_addr(env, addr, ntohl(in.s_addr)); |
1987 |
1963 |
1988 /* |
1964 /* |
1989 * For IP_MULTICAST_IF return InetAddress |
1965 * For IP_MULTICAST_IF return InetAddress |
1990 */ |
1966 */ |
1991 if (opt == java_net_SocketOptions_IP_MULTICAST_IF) { |
1967 if (opt == java_net_SocketOptions_IP_MULTICAST_IF) { |