997 } 998 999 if (addrP->brdcast != NULL) { 1000 tmpaddr->brdcast = (struct sockaddr *) ((char *) tmpaddr + sizeof(netaddr)+addr_size); 1001 memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size); 1002 } 1003 1004 tmpaddr->next = currif->addr; 1005 currif->addr = tmpaddr; 1006 } 1007 1008 return ifs; 1009 } 1010 1011 /* Open socket for further ioct calls 1012 * proto is AF_INET/AF_INET6 1013 */ 1014 static int openSocket(JNIEnv *env, int proto){ 1015 int sock; 1016 1017 if ((sock = JVM_Socket(proto, SOCK_DGRAM, 0)) < 0) { 1018 /* 1019 * If EPROTONOSUPPORT is returned it means we don't have 1020 * support for this proto so don't throw an exception. 1021 */ 1022 if (errno != EPROTONOSUPPORT) { 1023 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "Socket creation failed"); 1024 } 1025 return -1; 1026 } 1027 1028 return sock; 1029 } 1030 1031 1032 /** Linux, AIX **/ 1033 #if defined(__linux__) || defined(_AIX) 1034 /* Open socket for further ioct calls, try v4 socket first and 1035 * if it falls return v6 socket 1036 */ 1037 1038 #ifdef AF_INET6 1039 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1040 int sock; 1041 struct ifreq if2; 1042 1043 if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1044 if (errno == EPROTONOSUPPORT){ 1045 if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1046 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1047 return -1; 1048 } 1049 } 1050 else{ // errno is not NOSUPPORT 1051 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); 1052 return -1; 1053 } 1054 } 1055 1056 /* Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or IPv6 socket regardless of type 1057 of address of an interface */ 1058 1059 return sock; 1060 } 1061 1062 #else 1063 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1064 return openSocket(env,AF_INET); 1065 } 1451 *flags = (if2.ifr_flags & 0xffff); 1452 } else { 1453 *flags = if2.ifr_flags; 1454 } 1455 return 0; 1456 } 1457 1458 #endif 1459 1460 /** Solaris **/ 1461 #ifdef __solaris__ 1462 /* Open socket for further ioct calls, try v4 socket first and 1463 * if it falls return v6 socket 1464 */ 1465 1466 #ifdef AF_INET6 1467 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1468 int sock, alreadyV6 = 0; 1469 struct lifreq if2; 1470 1471 if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1472 if (errno == EPROTONOSUPPORT){ 1473 if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1474 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1475 return -1; 1476 } 1477 1478 alreadyV6=1; 1479 } 1480 else{ // errno is not NOSUPPORT 1481 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); 1482 return -1; 1483 } 1484 } 1485 1486 /** 1487 * Solaris requires that we have an IPv6 socket to query an 1488 * interface without an IPv4 address - check it here. 1489 * POSIX 1 require the kernel to return ENOTTY if the call is 1490 * inappropriate for a device e.g. the NETMASK for a device having IPv6 1491 * only address but not all devices follow the standard so 1492 * fall back on any error. It's not an ecologically friendly gesture 1493 * but more reliable. 1494 */ 1495 1496 if (! alreadyV6 ){ 1497 memset((char *) &if2, 0, sizeof(if2)); 1498 strcpy(if2.lifr_name, ifname); 1499 if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) { 1500 close(sock); 1501 if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1502 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1503 return -1; 1504 } 1505 } 1506 } 1507 1508 return sock; 1509 } 1510 1511 #else 1512 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1513 return openSocket(env,AF_INET); 1514 } 1515 #endif 1516 1517 /* 1518 * Enumerates and returns all IPv4 interfaces 1519 * (linux verision) 1520 */ 1521 1837 1838 *flags = lifr.lifr_flags; 1839 return 0; 1840 } 1841 1842 1843 #endif 1844 1845 1846 /** BSD **/ 1847 #ifdef _ALLBSD_SOURCE 1848 /* Open socket for further ioct calls, try v4 socket first and 1849 * if it falls return v6 socket 1850 */ 1851 1852 #ifdef AF_INET6 1853 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1854 int sock; 1855 struct ifreq if2; 1856 1857 if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1858 if (errno == EPROTONOSUPPORT){ 1859 if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1860 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1861 return -1; 1862 } 1863 } 1864 else{ // errno is not NOSUPPORT 1865 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); 1866 return -1; 1867 } 1868 } 1869 1870 return sock; 1871 } 1872 1873 #else 1874 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1875 return openSocket(env,AF_INET); 1876 } 1877 #endif 1878 1879 /* | 997 } 998 999 if (addrP->brdcast != NULL) { 1000 tmpaddr->brdcast = (struct sockaddr *) ((char *) tmpaddr + sizeof(netaddr)+addr_size); 1001 memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size); 1002 } 1003 1004 tmpaddr->next = currif->addr; 1005 currif->addr = tmpaddr; 1006 } 1007 1008 return ifs; 1009 } 1010 1011 /* Open socket for further ioct calls 1012 * proto is AF_INET/AF_INET6 1013 */ 1014 static int openSocket(JNIEnv *env, int proto){ 1015 int sock; 1016 1017 if ((sock = socket(proto, SOCK_DGRAM, 0)) < 0) { 1018 /* 1019 * If EPROTONOSUPPORT is returned it means we don't have 1020 * support for this proto so don't throw an exception. 1021 */ 1022 if (errno != EPROTONOSUPPORT) { 1023 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "Socket creation failed"); 1024 } 1025 return -1; 1026 } 1027 1028 return sock; 1029 } 1030 1031 1032 /** Linux, AIX **/ 1033 #if defined(__linux__) || defined(_AIX) 1034 /* Open socket for further ioct calls, try v4 socket first and 1035 * if it falls return v6 socket 1036 */ 1037 1038 #ifdef AF_INET6 1039 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1040 int sock; 1041 struct ifreq if2; 1042 1043 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1044 if (errno == EPROTONOSUPPORT){ 1045 if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1046 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1047 return -1; 1048 } 1049 } 1050 else{ // errno is not NOSUPPORT 1051 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); 1052 return -1; 1053 } 1054 } 1055 1056 /* Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or IPv6 socket regardless of type 1057 of address of an interface */ 1058 1059 return sock; 1060 } 1061 1062 #else 1063 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1064 return openSocket(env,AF_INET); 1065 } 1451 *flags = (if2.ifr_flags & 0xffff); 1452 } else { 1453 *flags = if2.ifr_flags; 1454 } 1455 return 0; 1456 } 1457 1458 #endif 1459 1460 /** Solaris **/ 1461 #ifdef __solaris__ 1462 /* Open socket for further ioct calls, try v4 socket first and 1463 * if it falls return v6 socket 1464 */ 1465 1466 #ifdef AF_INET6 1467 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1468 int sock, alreadyV6 = 0; 1469 struct lifreq if2; 1470 1471 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1472 if (errno == EPROTONOSUPPORT){ 1473 if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1474 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1475 return -1; 1476 } 1477 1478 alreadyV6=1; 1479 } 1480 else{ // errno is not NOSUPPORT 1481 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); 1482 return -1; 1483 } 1484 } 1485 1486 /** 1487 * Solaris requires that we have an IPv6 socket to query an 1488 * interface without an IPv4 address - check it here. 1489 * POSIX 1 require the kernel to return ENOTTY if the call is 1490 * inappropriate for a device e.g. the NETMASK for a device having IPv6 1491 * only address but not all devices follow the standard so 1492 * fall back on any error. It's not an ecologically friendly gesture 1493 * but more reliable. 1494 */ 1495 1496 if (! alreadyV6 ){ 1497 memset((char *) &if2, 0, sizeof(if2)); 1498 strcpy(if2.lifr_name, ifname); 1499 if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) { 1500 close(sock); 1501 if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1502 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1503 return -1; 1504 } 1505 } 1506 } 1507 1508 return sock; 1509 } 1510 1511 #else 1512 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1513 return openSocket(env,AF_INET); 1514 } 1515 #endif 1516 1517 /* 1518 * Enumerates and returns all IPv4 interfaces 1519 * (linux verision) 1520 */ 1521 1837 1838 *flags = lifr.lifr_flags; 1839 return 0; 1840 } 1841 1842 1843 #endif 1844 1845 1846 /** BSD **/ 1847 #ifdef _ALLBSD_SOURCE 1848 /* Open socket for further ioct calls, try v4 socket first and 1849 * if it falls return v6 socket 1850 */ 1851 1852 #ifdef AF_INET6 1853 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1854 int sock; 1855 struct ifreq if2; 1856 1857 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1858 if (errno == EPROTONOSUPPORT){ 1859 if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){ 1860 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); 1861 return -1; 1862 } 1863 } 1864 else{ // errno is not NOSUPPORT 1865 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); 1866 return -1; 1867 } 1868 } 1869 1870 return sock; 1871 } 1872 1873 #else 1874 static int openSocketWithFallback(JNIEnv *env, const char *ifname){ 1875 return openSocket(env,AF_INET); 1876 } 1877 #endif 1878 1879 /* |