133 #ifdef AF_INET6 |
133 #ifdef AF_INET6 |
134 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs); |
134 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs); |
135 #endif |
135 #endif |
136 |
136 |
137 static netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs, |
137 static netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs, |
138 struct sockaddr *ifr_addrP, int family, short prefix); |
138 struct sockaddr *ifr_addrP, struct sockaddr *ifr_broadaddrP, |
|
139 struct sockaddr *ifr_subnetaddrP, int family, short prefix); |
139 static void freeif(netif *ifs); |
140 static void freeif(netif *ifs); |
140 |
141 |
141 static int openSocket(JNIEnv *env, int proto); |
142 static int openSocket(JNIEnv *env, int proto); |
142 static int openSocketWithFallback(JNIEnv *env, const char *ifname); |
143 static int openSocketWithFallback(JNIEnv *env, const char *ifname); |
143 |
144 |
144 |
145 |
145 static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, |
146 static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, |
146 struct sockaddr *brdcast_store); |
147 struct sockaddr *brdcast_store); |
147 static short getSubnet(JNIEnv *env, int sock, const char *ifname); |
148 static short getSubnet(JNIEnv *env, int sock, const char *ifname); |
|
149 static short computeMaskFromAddress(struct sockaddr *ifr_subnetaddrP); |
148 static int getIndex(int sock, const char *ifname); |
150 static int getIndex(int sock, const char *ifname); |
149 |
151 |
150 static int getFlags(int sock, const char *ifname, int *flags); |
152 static int getFlags(int sock, const char *ifname, int *flags); |
151 static int getMacAddress(JNIEnv *env, int sock, const char *ifname, |
153 static int getMacAddress(JNIEnv *env, int sock, const char *ifname, |
152 const struct in_addr *addr, unsigned char *buf); |
154 const struct in_addr *addr, unsigned char *buf); |
862 currif = ifs; |
864 currif = ifs; |
863 } |
865 } |
864 } |
866 } |
865 |
867 |
866 netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs, |
868 netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs, |
867 struct sockaddr *ifr_addrP, int family, short prefix) |
869 struct sockaddr *ifr_addrP, struct sockaddr *ifr_broadaddrP, |
|
870 struct sockaddr *ifr_subnetaddrP, int family, short prefix) |
868 { |
871 { |
869 netif *currif = ifs, *parent; |
872 netif *currif = ifs, *parent; |
870 netaddr *addrP; |
873 netaddr *addrP; |
871 |
874 |
872 #ifdef LIFNAMSIZ |
875 #ifdef LIFNAMSIZ |
910 addrP->family = family; |
913 addrP->family = family; |
911 addrP->brdcast = NULL; |
914 addrP->brdcast = NULL; |
912 addrP->mask = prefix; |
915 addrP->mask = prefix; |
913 addrP->next = 0; |
916 addrP->next = 0; |
914 if (family == AF_INET) { |
917 if (family == AF_INET) { |
915 // Deal with broadcast addr & subnet mask |
918 // Deal with broadcast addr & subnet mask |
916 struct sockaddr *brdcast_to = |
919 if (ifr_broadaddrP != NULL) { // just set it, if already known |
917 (struct sockaddr *) ((char *)addrP + sizeof(netaddr) + addr_size); |
920 addrP->brdcast = |
918 addrP->brdcast = getBroadcast(env, sock, name, brdcast_to); |
921 (struct sockaddr *)((char *)addrP + sizeof(netaddr) + addr_size); |
919 if ((*env)->ExceptionCheck(env) == JNI_TRUE) { |
922 memcpy(addrP->brdcast, ifr_broadaddrP, addr_size); |
920 return ifs; |
923 } else { // otherwise look it up |
921 } |
924 struct sockaddr *brdcast_to = |
922 if ((mask = getSubnet(env, sock, name)) != -1) { |
925 (struct sockaddr *)((char *)addrP + sizeof(netaddr) + addr_size); |
923 addrP->mask = mask; |
926 addrP->brdcast = getBroadcast(env, sock, name, brdcast_to); |
924 } else if((*env)->ExceptionCheck(env)) { |
927 if ((*env)->ExceptionCheck(env) == JNI_TRUE) { |
925 return ifs; |
928 return ifs; |
926 } |
929 } |
927 } |
930 } |
|
931 |
|
932 if (ifr_subnetaddrP != NULL) { // just compute the mask, if already known |
|
933 addrP->mask = computeMaskFromAddress(ifr_subnetaddrP); |
|
934 } else { // otherwise look it up |
|
935 if ((mask = getSubnet(env, sock, name)) != -1) { |
|
936 addrP->mask = mask; |
|
937 } else if((*env)->ExceptionCheck(env)) { |
|
938 return ifs; |
|
939 } |
|
940 } |
|
941 } |
928 |
942 |
929 // Deal with virtual interface with colon notation e.g. eth0:1 |
943 // Deal with virtual interface with colon notation e.g. eth0:1 |
930 name_colonP = strchr(name, ':'); |
944 name_colonP = strchr(name, ':'); |
931 if (name_colonP != NULL) { |
945 if (name_colonP != NULL) { |
932 // This is a virtual interface. If we are able to access the parent |
946 // This is a virtual interface. If we are able to access the parent |
1120 return ifs; |
1148 return ifs; |
1121 } |
1149 } |
1122 |
1150 |
1123 // Iterate through each interface |
1151 // Iterate through each interface |
1124 ifreqP = ifc.ifc_req; |
1152 ifreqP = ifc.ifc_req; |
|
1153 struct sockaddr addr, broadaddr, netmask; |
1125 for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++, ifreqP++) { |
1154 for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++, ifreqP++) { |
|
1155 struct sockaddr* broadaddrP = NULL; |
|
1156 struct sockaddr* subnetaddrP = NULL; |
|
1157 |
|
1158 // Ignore non IPv4 Interfaces |
|
1159 if ((struct sockaddr *)&(ifreqP->ifr_addr) != NULL && |
|
1160 ((struct sockaddr *)&(ifreqP->ifr_addr))->sa_family != AF_INET) { |
|
1161 continue; |
|
1162 } |
|
1163 |
|
1164 memcpy(&addr, &(ifreqP->ifr_addr), sizeof(struct sockaddr)); |
|
1165 |
|
1166 // set broadaddrP, if applicable |
|
1167 if ((ifreqP->ifr_flags & IFF_POINTOPOINT) == 0 && |
|
1168 ifreqP->ifr_flags & IFF_BROADCAST) { |
|
1169 |
|
1170 if (ioctl(sock, SIOCGIFBRDADDR, ifreqP) == 0) { |
|
1171 memcpy(&broadaddr, &(ifreqP->ifr_broadaddr), sizeof(struct sockaddr)); |
|
1172 broadaddrP = &broadaddr; |
|
1173 } |
|
1174 // restore the address, for subsequent calls |
|
1175 memcpy(&(ifreqP->ifr_addr), &addr, sizeof(struct sockaddr)); |
|
1176 } |
|
1177 |
|
1178 if (ioctl(sock, SIOCGIFNETMASK, ifreqP) == 0) { |
1126 #if defined(_AIX) |
1179 #if defined(_AIX) |
1127 if (ifreqP->ifr_addr.sa_family != AF_INET) continue; |
1180 memcpy(&netmask, &(ifreqP->ifr_addr), sizeof(struct sockaddr)); |
1128 #endif |
1181 #else |
|
1182 memcpy(&netmask, &(ifreqP->ifr_netmask), sizeof(struct sockaddr)); |
|
1183 #endif |
|
1184 subnetaddrP = &netmask; |
|
1185 } |
|
1186 |
1129 // Add to the list |
1187 // Add to the list |
1130 ifs = addif(env, sock, ifreqP->ifr_name, ifs, |
1188 ifs = addif(env, sock, ifreqP->ifr_name, ifs, |
1131 (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET, 0); |
1189 &addr, broadaddrP, subnetaddrP, AF_INET, 0); |
1132 |
1190 |
1133 // If an exception occurred then free the list |
1191 // If an exception occurred then free the list |
1134 if ((*env)->ExceptionOccurred(env)) { |
1192 if ((*env)->ExceptionOccurred(env)) { |
1135 free(buf); |
1193 free(buf); |
1136 freeif(ifs); |
1194 freeif(ifs); |
1175 memcpy((void*)addr.sin6_addr.s6_addr, (const void*)ipv6addr, 16); |
1233 memcpy((void*)addr.sin6_addr.s6_addr, (const void*)ipv6addr, 16); |
1176 |
1234 |
1177 addr.sin6_scope_id = if_idx; |
1235 addr.sin6_scope_id = if_idx; |
1178 |
1236 |
1179 ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, |
1237 ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, |
1180 AF_INET6, (short)prefix); |
1238 NULL, NULL, AF_INET6, (short)prefix); |
1181 |
1239 |
1182 // If an exception occurred then return the list as is. |
1240 // If an exception occurred then return the list as is. |
1183 if ((*env)->ExceptionOccurred(env)) { |
1241 if ((*env)->ExceptionOccurred(env)) { |
1184 fclose(f); |
1242 fclose(f); |
1185 return ifs; |
1243 return ifs; |
1259 s6->sin6_scope_id = if2.ifr_site6; |
1317 s6->sin6_scope_id = if2.ifr_site6; |
1260 } |
1318 } |
1261 |
1319 |
1262 // Add to the list |
1320 // Add to the list |
1263 ifs = addif(env, sock, ifreqP->ifr_name, ifs, |
1321 ifs = addif(env, sock, ifreqP->ifr_name, ifs, |
1264 (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET6, 0); |
1322 (struct sockaddr *)&(ifreqP->ifr_addr), |
|
1323 NULL, NULL, AF_INET6, 0); |
1265 |
1324 |
1266 // If an exception occurred then free the list |
1325 // If an exception occurred then free the list |
1267 if ((*env)->ExceptionOccurred(env)) { |
1326 if ((*env)->ExceptionOccurred(env)) { |
1268 free(buf); |
1327 free(buf); |
1269 freeif(ifs); |
1328 freeif(ifs); |
1344 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", |
1403 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", |
1345 "ioctl SIOCGIFNETMASK failed"); |
1404 "ioctl SIOCGIFNETMASK failed"); |
1346 return -1; |
1405 return -1; |
1347 } |
1406 } |
1348 |
1407 |
1349 mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr); |
1408 return computeMaskFromAddress(&(if2.ifr_addr)); |
1350 ret = 0; |
|
1351 while (mask) { |
|
1352 mask <<= 1; |
|
1353 ret++; |
|
1354 } |
|
1355 |
|
1356 return ret; |
|
1357 } |
1409 } |
1358 |
1410 |
1359 /* |
1411 /* |
1360 * Gets the Hardware address (usually MAC address) for the named interface. |
1412 * Gets the Hardware address (usually MAC address) for the named interface. |
1361 * On return puts the data in buf, and returns the length, in byte, of the |
1413 * On return puts the data in buf, and returns the length, in byte, of the |
1593 } |
1645 } |
1594 #endif |
1646 #endif |
1595 |
1647 |
1596 // add to the list |
1648 // add to the list |
1597 ifs = addif(env, sock,ifr->lifr_name, ifs, |
1649 ifs = addif(env, sock,ifr->lifr_name, ifs, |
1598 (struct sockaddr *)&(ifr->lifr_addr), family, |
1650 (struct sockaddr *)&(ifr->lifr_addr), |
1599 (short)ifr->lifr_addrlen); |
1651 NULL, NULL, family, (short)ifr->lifr_addrlen); |
1600 |
1652 |
1601 // If an exception occurred we return immediately |
1653 // If an exception occurred we return immediately |
1602 if ((*env)->ExceptionOccurred(env)) { |
1654 if ((*env)->ExceptionOccurred(env)) { |
1603 free(buf); |
1655 free(buf); |
1604 return ifs; |
1656 return ifs; |
1887 "getifaddrs() function failed"); |
1931 "getifaddrs() function failed"); |
1888 return ifs; |
1932 return ifs; |
1889 } |
1933 } |
1890 |
1934 |
1891 for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) { |
1935 for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) { |
|
1936 struct sockaddr* ifa_broadaddr = NULL; |
1892 |
1937 |
1893 // Skip non-AF_INET entries. |
1938 // Skip non-AF_INET entries. |
1894 if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET) |
1939 if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET) |
1895 continue; |
1940 continue; |
1896 |
1941 |
|
1942 // set ifa_broadaddr, if there is one |
|
1943 if ((ifa->ifa_flags & IFF_POINTOPOINT) == 0 && |
|
1944 ifa->ifa_flags & IFF_BROADCAST) { |
|
1945 ifa_broadaddr = ifa->ifa_broadaddr; |
|
1946 } |
|
1947 |
1897 // Add to the list. |
1948 // Add to the list. |
1898 ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET, 0); |
1949 ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, |
|
1950 ifa_broadaddr, ifa->ifa_netmask, AF_INET, 0); |
1899 |
1951 |
1900 // If an exception occurred then free the list. |
1952 // If an exception occurred then free the list. |
1901 if ((*env)->ExceptionOccurred(env)) { |
1953 if ((*env)->ExceptionOccurred(env)) { |
1902 freeifaddrs(origifa); |
1954 freeifaddrs(origifa); |
1903 freeif(ifs); |
1955 freeif(ifs); |
1969 return NULL; |
2021 return NULL; |
1970 } |
2022 } |
1971 |
2023 |
1972 // Add to the list. |
2024 // Add to the list. |
1973 sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr; |
2025 sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr; |
1974 ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET6, |
2026 ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, NULL, NULL, |
1975 (short)prefix(&sin6->sin6_addr, sizeof(struct in6_addr))); |
2027 AF_INET6, |
|
2028 (short)prefix(&sin6->sin6_addr, sizeof(struct in6_addr))); |
1976 |
2029 |
1977 // If an exception occurred then free the list. |
2030 // If an exception occurred then free the list. |
1978 if ((*env)->ExceptionOccurred(env)) { |
2031 if ((*env)->ExceptionOccurred(env)) { |
1979 freeifaddrs(origifa); |
2032 freeifaddrs(origifa); |
1980 freeif(ifs); |
2033 freeif(ifs); |
2057 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", |
2110 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", |
2058 "ioctl SIOCGIFNETMASK failed"); |
2111 "ioctl SIOCGIFNETMASK failed"); |
2059 return -1; |
2112 return -1; |
2060 } |
2113 } |
2061 |
2114 |
2062 mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr); |
2115 return computeMaskFromAddress(&(if2.ifr_addr)); |
2063 ret = 0; |
|
2064 while (mask) { |
|
2065 mask <<= 1; |
|
2066 ret++; |
|
2067 } |
|
2068 |
|
2069 return ret; |
|
2070 } |
2116 } |
2071 |
2117 |
2072 /* |
2118 /* |
2073 * Gets the Hardware address (usually MAC address) for the named interface. |
2119 * Gets the Hardware address (usually MAC address) for the named interface. |
2074 * return puts the data in buf, and returns the length, in byte, of the |
2120 * return puts the data in buf, and returns the length, in byte, of the |